[.NET] Reflection

Pagina: 1
Acties:

  • whoami
  • Registratie: December 2000
  • Laatst online: 23-05 16:52
Ik heb een applicatie, en ik zou willen dat die applicatie type-informatie kan halen uit de (eigen, custom) assemblies die in die applicatie gereferenced zijn.

Mijn idee is dus, dat ik als eerste de 'referenced assemblies' kan bepalen. Ik dacht dat ik dat kon doen via deze code:

code:
1
this.GetType().GetReferencedAssemblies();


Deze method returned een array van AssemblyNames. Echter, als ik al die assembly-names bekijk, dan zie ik dat mijn custom assemblies er niet bij zitten?

Mocht dit wel het geval zijn, dan zou het een eitje zijn om de types die in die assemblies gedeclareerd zijn te gaan halen.

Weet iemand hoe ik dit kan verwezenlijken? Hoe kan ik type-informatie gaan halen van custom types uit custom assemblies waar m'n applicatie naar refereert?

https://fgheysels.github.io/


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

Moet dat niet zo:
C#:
1
Assembly.GetExecutingAssembly().GetReferencedAssemblies();
?

En anders middels deze:
C#:
1
2
foreach(System.Reflection.Module module in Assembly.GetExecutingAssembly().GetModules())
  Console.WriteLine(module.Assembly.Name);

Professionele website nodig?


  • whoami
  • Registratie: December 2000
  • Laatst online: 23-05 16:52
Die code is idd mooier, maar het resultaat is hetzelfde.

Mijn custom assemblies (die hebben geen strong name btw), worden blijkbaar niet in dat lijstje meegenomen.
Ik krijg te zien: System.Windows.Forms, mscorlib, etc....

https://fgheysels.github.io/


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

Probeer eens of een strong name iets uitmaakt? Lijkt me namelijk niet onlogisch dat dat scheelt (waarom een naam noemen van iets waarvan je niet kunt garanderen dat het uniek is :) )

Professionele website nodig?


  • dotcode
  • Registratie: Augustus 2003
  • Laatst online: 22-05 10:39

dotcode

///\00/\\

Ik denk dat je hier wel wat aan kan hebben:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Assembly assembly = Assembly.LoadFile(filenaam);

                        
                foreach (Type type in assembly.GetTypes())
                {
                    if (type.IsClass && HasInterface(type, typeof(IMYIMTERFACE)))
                    {
                        try 
                        {
                            IMYINETERFACE i = (IMYINETERFACE )Activator.CreateInstanceFrom(filenaam, type.ToString()).Unwrap();
                        //Doe je dingetje                       }
                        catch (Exception ex)
                        {   
                            Console.WriteLine(ex);
                        }
                    }
                }


Het doet net niet wat je wilt maar wel bijna, ik heb de belangrijke code voor mij zelf er even uit gehaald.

Daarnaast gebruik ik geen strongnames

[ Voor 10% gewijzigd door dotcode op 07-09-2004 16:08 ]


  • whoami
  • Registratie: December 2000
  • Laatst online: 23-05 16:52
Zoiets had ik ook al ongeveer in gedachten, maar mijn probleem is dus dat ik eigenlijk niet weet welke assemblies er gereferenced zijn, of hoe die heten.

curry: ook met een assembly met een strong name die in de GAC zit lukt het niet.
Misschien moeten ze eerst in het AppDomain ingeladen zijn ofzo.

https://fgheysels.github.io/


  • dotcode
  • Registratie: Augustus 2003
  • Laatst online: 22-05 10:39

dotcode

///\00/\\

Mag ik vragen waar je het precies voor wilt gaan gebruiken, je kan die dingen natuurlijk uitvoeren. Maar als je niet weet wat het doet is de kans natuurlijk klein dat het goed gaat. Ik zou zeggen dat je dan altijd een interface met een service discriptie zou moeten hebben ipv alle methode random te invoken. Je kan natuurlijk een tree van de signatures weergeven en een soort test interace maken waarbij je ze kan uitvoeren, lijkt me best aardig voor functies die simpletypes als parameters hebben. Daarnaast mis je waarschijnlijk state in de objecten bij een invoke, waardoor het veel minder nuttig wordt. Maar er zijn natuurlijk andere toepassingen...

Verwijderd

Als het echt niet anders wil zou je een pre-built visual studio addin kunnen maken die de referenced assemblies uit de visual studio environment leest en deze in een file zet. Da heeft natuurlijk alleen zin als je je applicatie bouwt met VS... Ik heb geen idee of je die file ook nog als resource aan je exe toe kunt voegen; dat zou natuurlijk helemaal prettig zijn.

Hoe je de referenced assemblies @runtime bepaalt weet ik helaas niet..

  • whoami
  • Registratie: December 2000
  • Laatst online: 23-05 16:52
Ja, daar heb je wel gelijk in.
Ik wil dan ook niet zomaar 'alle' types gaan ophalen, maar de types die een bepaalde interface implementeren.

https://fgheysels.github.io/


Verwijderd

Misschien is de oplossing om alle assemblies die je gebruikt in een aparte directory te zetten en deze te scannen op types die een bepaalde interface implementeren.

Deze methode heb ik gebruikt om met plugins te kunnen werken.
Zorg er wel voor dat je tijdens het scannen de te testen assemblies inlaadt in een ander AppDomain anders blijven ze ingeladen, of ze nu nodig zijn of nie.

Of zie ik het probleem te simpel?

  • dotcode
  • Registratie: Augustus 2003
  • Laatst online: 22-05 10:39

dotcode

///\00/\\

Om alles wat is geladen te kunnen bekijken kan je kijken in:
code:
1
Assembly a in AppDomain.CurrentDomain.GetAssemblies()


volgens mij kijkt de code boven all naar de interfaces


Je zou natuurlijk met attributes kunnen gaan werken wat ook heel leuk is.

[ Voor 18% gewijzigd door dotcode op 07-09-2004 17:30 ]


  • whoami
  • Registratie: December 2000
  • Laatst online: 23-05 16:52
Nog een reflection - vraagje....

Met de IsSubClassOf method van de Type class, kan je nagaan of een type van een bepaalde class inherit.
Ik dacht dat dit ook met interfaces ging werken; maw, ik dacht dat deze method ook true ging opleveren als m'n type een bepaalde interface die ik meegaf aan die IsSubClassOf method implementeerde.
Dat is jammer genoeg niet het geval.
Weet er iemand hoe ik kan bepalen of een bepaald type een bepaalde interface implementeerd?

https://fgheysels.github.io/


  • whoami
  • Registratie: December 2000
  • Laatst online: 23-05 16:52
Ok, ik heb een oplossing gevonden voor m'n bovenstaande probleem, maar ik ben er niet zo helemaal tevreden over:

code:
1
if( myType.GetInterface("IMigrator") == typeof(IMigrator) )

Zoals je ziet, moet ik m'n interface naam als een string meegeven, en dat doe ik liever niet.
Nu kan ik het natuurlijk wel zo doen:
code:
1
myType.GetInterface (typeof(IMigrator).Name)

maar ik vraag me af of er geen eenvoudigere oplossing is.

https://fgheysels.github.io/


Verwijderd

ik heb dit zo gedaan

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
Assembly asm    = AppDomain.CurrentDomain.Load(path);
                
                foreach(Type t in  asm.GetTypes())
                {
                    foreach(Type iface in  t.GetInterfaces())       
                    {
                        if(iface.Equals(typeof(IEventPlugin)))
                        {
                            m_GoodIEventTypes.Add(t.ToString(), t);
                            break; 
                        }
                    }
                }

  • whoami
  • Registratie: December 2000
  • Laatst online: 23-05 16:52
Hmm, dan vind ik mijn implementatie iets mooier, aangezien je toch weet op welke interface je moet checken, en je dus niet hoeft te loopen door alle interfaces.

https://fgheysels.github.io/


  • Sjaaky
  • Registratie: Oktober 2000
  • Laatst online: 22-04 07:04
code:
1
myType.IsInstanceOfType( typeof(IMigrator) )

Niet getest, maar niet geschoten is altijd mis.

Verwijderd

whoami schreef op 08 september 2004 @ 17:22:
Hmm, dan vind ik mijn implementatie iets mooier, aangezien je toch weet op welke interface je moet checken, en je dus niet hoeft te loopen door alle interfaces.
die eerst lus is om alle types in één bepaalde assembly te bekijken, er kunnen meerdere classes in een dll bestand zitten
de tweede lus is misschien wel overbodig en dan kan je dat op jouw manier oplossen

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-05 23:07

.oisyn

Moderator Devschuur®

Demotivational Speaker

Sjaaky schreef op 08 september 2004 @ 17:53:
code:
1
myType.IsInstanceOfType( typeof(IMigrator) )

Niet getest, maar niet geschoten is altijd mis.
Dat gaat niet werken. IsInstanceOfType test of een bepaald object een instantie is van het type dat je hebt. De typeof operator returned een instantie van het type Type, en dat is dus niet een instantie van het type dat gerepresenteert wordt door myType.

[ Voor 197% gewijzigd door .oisyn op 09-09-2004 02:34 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • whoami
  • Registratie: December 2000
  • Laatst online: 23-05 16:52
Verwijderd schreef op 08 september 2004 @ 18:16:
[...]


die eerst lus is om alle types in één bepaalde assembly te bekijken, er kunnen meerdere classes in een dll bestand zitten
de tweede lus is misschien wel overbodig en dan kan je dat op jouw manier oplossen
Idd, die eerste lus, daar kan je niet vanuit (die heb ik trouwens ook). Die 2de lus heb ik niet. :P

https://fgheysels.github.io/

Pagina: 1