Toon posts:

[VB.Net] Plugin systeem (laden van assemblies)

Pagina: 1
Acties:

Verwijderd

Topicstarter
Voor mijn Browser wil ik een plugin systeem gaan maken. Ik heb het GoT doorzocht en met Google gezocht, maar heb niets kunnen vinden.

Browser op GoT: [rml][ Browser] Wat wil jij in een browser?[/rml]

Hier de code uit mijn testapplicatie:
Visual Basic .NET:
1
2
3
4
5
6
7
8
9
10
    Private Sub Button1_Click(...) Handles Button1.Click
        Dim ofd As New OpenFileDialog
        ofd.Filter = "DLL files|*.dll"
        if ofd.ShowDialog() = DialogResult.OK then
             Dim asm As System.Reflection.Assembly
             asm = asm.LoadFrom(ofd.FileName)
             Dim o As Object = asm.CreateInstance("???")
             o.PreformAction() '< De routine die ik in mijn assembly gemaakt heb.
        end if
    End Sub


De bovenstaande code werkt duidelijk niet, ik krijg een exception. Kunnen jullie me helpen met dit probleem? Bij voorbaat dank :D

  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 17:26

gorgi_19

Kruimeltjes zijn weer op :9

En wij mogen nu raden welke foutmelding je krijgt? :) Welke krijg je? Heb je al gezocht in Google op reflection? Heb je al gezocht op de foutmelding?

Digitaal onderwijsmateriaal, leermateriaal voor hbo


  • mulder
  • Registratie: Augustus 2001
  • Laatst online: 06-05 12:34

mulder

ik spuug op het trottoir

oogjes open, snaveltjes dicht


  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 06-05 18:51

Creepy

Tactical Espionage Splatterer

En bekijk ook meteen P&W FAQ - De "quickstart"
Er missen namelijk nogal wat zaken. Welke Exception krijg je? Waar krijg je die (in de code die je post, of in je eigen assembly? Ben je al stap voor stap door je code heen gewandeld om te kijken wat er mis gaat? Zie ook P&W FAQ - Leer **** debuggen!!

[ Voor 8% gewijzigd door Creepy op 26-05-2005 15:00 ]

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • whoami
  • Registratie: December 2000
  • Laatst online: 17:15
Jij hebt nu een assembly geladen, en een type uit die assembly geladen.
Echter, die CreateInstance method waarmee je een type (een instance van een class uit die assembly bv) creeërt, returned een object.
Op dat 'object' wil jij dan een method uitvoeren, maar die 'method' behoort niet tot de interface van object. (Wat logisch is, want object is de root van alle classes).
Je zult dus eerst nog dat 'object' moeten casten naar het type dat je eigenlijk hebt geladen.

code:
1
2
3
4
5
6
7
8
9
10
11
12
o = asm.CreateInstance ("MyNamespace.MyType");

MyType t = o as MyType;

if( t != null )
{
    t.DoSomething();
}
else
{
    throw new InvalidOperationException ("Requested type could not be found.");
}


Check ook dit:
[rml][ .NET] Dynamisch laden van assemblies[/rml]

[ Voor 6% gewijzigd door whoami op 26-05-2005 15:10 ]

https://fgheysels.github.io/


Verwijderd

Topicstarter
De foutmelding:
"An unhandled exception of type 'System.NullReferenceException' occurred in microsoft.visualbasic.dll" (op regel 8 ) Dat gaat me dus niet verder helpen.

Na ff zoeken op Reflection. Heb ik dit in elkaar weten te zetten
Visual Basic .NET:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
    Private asm As [Assembly]
    Private ClassTypes As Type() = Nothing
    Private mi As MethodInfo()

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim ofd As New OpenFileDialog
        Dim i As Integer
        ofd.Filter = "DLL files|*.dll"
        ofd.ShowDialog()
        asm = [Assembly].LoadFrom(ofd.FileName)
        ClassTypes = asm.GetTypes
        lstClass.Items.Clear()

        For i = 0 To ClassTypes.Length - 1
            Me.lstClass.Items.Add(ClassTypes(i).Name)
        Next
    End Sub

    Private Sub lstClass_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lstClass.SelectedIndexChanged
        mi = ClassTypes(lstClass.SelectedIndex).GetMethods
        lbMethods.Items.Clear()
        Dim i As Integer
        For i = 0 To mi.Length - 1
            lbMethods.Items.Add(mi(i).Name)
        Next
    End Sub


Ik krijg nu te zien welke types er in een assembly zitten en wat de methoden daarvan zijn. Maar, ik kan ze nog steeds niet uitvoeren.
Dit staat namenlijk niet in de webpagina's die ik bezocht heb... en ik weet het zelf ook niet :o

  • whoami
  • Registratie: December 2000
  • Laatst online: 17:15
...hmm beetje voorbarig misschien...

[ Voor 94% gewijzigd door whoami op 26-05-2005 15:36 ]

https://fgheysels.github.io/


  • whoami
  • Registratie: December 2000
  • Laatst online: 17:15
Je hebt nog steeds geen type gemaakt.

Je moet dus eerst een object instantieren uit die DLL, vooraleer je een method van dat object kunt uitvoeren.

https://fgheysels.github.io/


Verwijderd

Topicstarter
dus de code:

Visual Basic .NET:
1
2
Dim o As Object = asm.CreateInstance("Plugin.MijnPlugin") 
o.Start()


moet dan werken?

  • whoami
  • Registratie: December 2000
  • Laatst online: 17:15
Neen, je leest mijn reply niet goed.

Check dit nog eens:
[rml]whoami in "[ VB.Net] Plugin systeem (laden van assem..."[/rml]

Je moet dat object dus eerst nog casten naar het gewenste type.

[ Voor 17% gewijzigd door whoami op 26-05-2005 16:26 ]

https://fgheysels.github.io/


Verwijderd

Topicstarter
Maar hoe ga ik een object casten naar een type waarvan ik nog niet weet wat het is? (in VB)

--

Visual Basic .NET:
1
mi(lbMethods.SelectedIndex).Invoke(...., ....)

Dit lijkt op de oplossing, maar wat moet ik hier op de puntjes invullen?

  • whoami
  • Registratie: December 2000
  • Laatst online: 17:15
Ik zou er voor zorgen dat de objecten / types waarvan je wilt dat ze dmv een plugin at runtime / dynamisch kunnen geladen worden, allemaal dezelfde interface implementeren.

Dan kan je dat object casten naar die interface, en kan je de method oproepen die je in die interface gedefinieerd hebt, en die ieder object dan implementeert.

https://fgheysels.github.io/


Verwijderd

De methode die whoami aanhaalt is inderdaad de simpelste oplossing.

Ook zou ik nog de dll's die je probeert te laden eerst laden in een ander AppDomain.
Als je nl de dll's laadt dan blijven ze in het AppDomain zitten, of je ze nu gebruikt of niet.
Dus : nieuw AppDomain maken, daarin alle dll's inspecteren en enkel diegene die je nodig hebt teruggeven. Daarna AppDomain verwijderen.

Verwijderd

Topicstarter
Dat is niet nodig, er wordt maar één DLL geladen..

Maar, het lukt me nog steeds niet :S
Visual Basic .NET:
1
2
3
4
5
Dim o As Object = asm.CreateInstance(lstClass.GetItemText(lstClass.SelectedItem))
Dim t As Type
t = GetType(IPlugin) 'IPlugin is de Interface
Dim ipl As IPlugin = Convert.ChangeType(o, t)
ipl.start()


met een nullref. exception op de één na laatste regel crashed mijn testprogramma.

[ Voor 8% gewijzigd door Verwijderd op 27-05-2005 16:22 ]


  • whoami
  • Registratie: December 2000
  • Laatst online: 17:15
Nu, ik geen geen vb.net, maar als je een nullref hebt, dan wil het meestal zeggen dat de convert niet gelukt is.

https://fgheysels.github.io/


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
hij krijgt daar de NullReferenceException waarschijnlijk omdat hij "o" of "t" null is. t zal waarschijnlijk niet Null zijn want anders had je waarschijnlijk al een compiler error gehad dat hij IPlugin niet kent. Blijkbaar is asm.CreateInstance dus niet gelukt.

Dus controleer eerst eens of je wel degelijk een instance van je object terug krijgt.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”

Pagina: 1