[C#] Assembly dynamisch ophalen dmv de Reflection API

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Hallo tweakers!

Ik ben een applicatie aan het maken dat dynamisch een of meerdere assemblies moet kunnen includen, dit doe ik dmv reflection. Het idee erachter is een soort van plugin systeem.

Omdat het een plugin systeem is wil ik om zeker te zijn een interface hebben op de classes in de dll files. Het interface heb ik in een apparte assembly opgeslagen en die voeg ik als reference toe bij het maken van een plugin assembly.

Mijn interface:

C#:
1
2
3
4
5
6
7
8
9
10
11
namespace proxyPlugin
{
    public interface plugin
    {
        string getName();
        string getVersion();
        bool enableProxy();
        bool disableProxy();
        bool setProxy(string host, int port);
    }
}


Die gebruik ik zo op mijn plugin:

C#:
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
27
28
29
30
31
32
using proxyPlugin;

namespace windows
{
    public class windows : plugin
    {
        public string getName()
        {
            //..
        }

        public string getVersion()
        {
            //..
        }

        public bool enableProxy()
        {
           //..
        }

        public bool disableProxy()
        {
            //..
        }

        public bool setProxy(string host, int port)
        {
            //..
        }

}   


De plugin bestanden sla ik vervolgens op in een "/plugin" directory van de applicatie. In de applicatie zelf lees ik dus vervolgens de plugin directory op alle .dll bestanden. Als ik deze allemaal gevonden heb ga ik de array uitlezen en met reflection:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// Laad class van de plugin dmv reflection
Assembly pluginAsm = Assembly.LoadFrom(pluginInfo.FullName);
Type[] asmtypes = pluginAsm.GetTypes();

foreach(Type curType in asmtypes) 
{
    if (curType.IsClass && curType.IsPublic)
    {
        if (curType.GetInterface("plugin", true) == null)
        {
            continue;
        }

        MethodInfo[] methods = curType.GetMethods();
        foreach (MethodInfo method in methods)
        {
            MessageBox.Show(method.ToString());
        }
    }
}


Als ik nu de "windows" class ga lezen vind hij hem perfect en ook alle methods die de class heeft. Maar hij loopt vast bij if (curType.GetInterface("plugin", true) == null) terwijl de class wel degelijk de plugin interface gebruikt.

Ik ben hier nu al 2 dagen mee aan het stoeien maar het wil maar niet lukken :S. Kan iemand mij hier mee helpen? Alvast bedankt!

Acties:
  • 0 Henk 'm!

  • MrBucket
  • Registratie: Juli 2003
  • Laatst online: 29-10-2022
Probeer eens wat curType.IsAssignableFrom(typeof(plugin)) teruggeeft, of probeer curType.GetInterfaceMap().

Sowiezo: plaats eens een breakpoint op je test-statement en kijk eens met de debugger door de members van curType, volgens mij moet je daar ook een eind mee komen. :)

Edit: moet je trouwens niet testen op "proxyPlugin.plugin" i.p.v. "plugin"? O-)

[ Voor 13% gewijzigd door MrBucket op 16-08-2008 20:32 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Bedankt voor je reactie MrBucket!

Ik had proxyPlugin.plugin al geprobeerd en dat werkte toen al niet. Ik probeerde zojuist ook de twee andere opties, maar die lijken beide niet te werken :(

Het lijkt me wel of iets verkeerd doe in de plugin architecteur ofzo. Ik heb heb de interface dll in de plugin directory voor de plugins en ik heb hem ook in de debug directory voor de applicatie. In de applicatie gebruik ik hem ook als reference, maar dan die gene uit dezelfde direcory. Doe ik hier mischien wat fout?

Acties:
  • 0 Henk 'm!

  • MrBucket
  • Registratie: Juli 2003
  • Laatst online: 29-10-2022
Verwijderd schreef op zaterdag 16 augustus 2008 @ 20:56:
Bedankt voor je reactie MrBucket!

Ik had proxyPlugin.plugin al geprobeerd en dat werkte toen al niet. Ik probeerde zojuist ook de twee andere opties, maar die lijken beide niet te werken :(

Het lijkt me wel of iets verkeerd doe in de plugin architecteur ofzo. Ik heb heb de interface dll in de plugin directory voor de plugins en ik heb hem ook in de debug directory voor de applicatie. In de applicatie gebruik ik hem ook als reference, maar dan die gene uit dezelfde direcory. Doe ik hier mischien wat fout?
Dat ligt eraan of de plugin interface die je implementeert op je windows class, als dezelfde interface wordt gezien als de plugin interface die je gebruikt om de reflection calls mee uit te voeren. Wat de precieze regels daaromtrent zijn weet ik niet, maar het meest veilig ben je wanneer beide assemblies naar hetzelfde bestand verwijzen (die met de plugin interface-definitie dus).

Oh, en nog een idee: roep Type.GetInterfaces(curType) eens aan, en druk de namen van alle geretourneerde types eens af. 't Moet raar lopen als daar geen "plugin" in voorkomt.

En wat je ook nog kan proberen is alles (plugin interface, windows class en reflection code) in eerste instantie in dezelfde assembly stoppen, en controleren dat je reflection code de interface nu wel kan vinden op je windows class (zo niet, dan zal het in verschillende assemblies helemaal niet werken he...). Vervolgens probeer je ofwel de windows class, ofwel je reflection code af te splitsen naar een aparte assembly, en dan weer kijken of het werkt, etc. Geleidelijk aan moet je dan een indicatie kunnen krijgen waar het scheef gaat :)

[ Voor 18% gewijzigd door MrBucket op 16-08-2008 21:18 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Wederom bedankt :).

Blijkbaar zit er geen interface in. Zodra ik de inhoud van GetInterfaces afdruk krijg ik helemaal niks. Dan zal er blijkbaar wat in mijn plugin dll verkeerd gaan, ik kreeg het interface ook niet te zien met de Object Browser over de windows.dll assembly, maar ik zou niet weten of dat standaard is of niet.

Ik ga nog eens kijken naar me plugin voor ik alles in een assembly stop. :)

Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 23:07
Hmm, moet je niet de qualified name opgeven ?
code:
1
if( curType.GetInterface ("namespacename.interfacename") == null ) continue;

bv ?

En is het niet makkelijker als je het zo doet ?
code:
1
if( curType.GetInterface (typeof(IPlugin).Name) )

?

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Hmm wederom werkt het niet :S. Ik kan me niet meer voorstellen dat het aan me reflection code ligt. Ik denk dat ik ergens bij het maken van die plugin iets gruwlijk fout heb gedaan.

Ik heb hier me interface dll geupload, en hier me plugin. Zien jullie mischien iets wat fout is? :S

Wederom alvast bedankt.

Acties:
  • 0 Henk 'm!

  • MLM
  • Registratie: Juli 2004
  • Laatst online: 12-03-2023

MLM

aka Zolo

mijn ILDASM zegt over windows.dll
manifest
- .assembly extern 'interface'
windows.windows
- implements ['interface']proxyPlugin.plugin
en over plugin_interface.dll
manifest
- .assembly 'interface'
de namen kloppen allemaal, dus ik snap niet waarom het niet werkt.
Misschien (ben niet zo in thuis) moet je plugin_interface.dll echt 'interface'(.dll?) heten om de interface eruit te pakken...

[ Voor 5% gewijzigd door MLM op 17-08-2008 12:59 ]

-niks-


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Hardstikke bedankt MLM! Het werkte! :)

Dit is de eerste keer dat ik met een dll assembly werk dus ik had de interface dll gerust veranderd naar plugin_interface omdat ik niet had verwacht dat het iets uit zou maken. Verkeerd gedacht dus. :)

Maar goed ik ga weer verder met mijn code, vanaf dit punt verwacht ik niet meer al te veel tegenslagen. :)

Iedereen bedankt!
Pagina: 1