[C#] Reflection probleem met Custom Attributes

Pagina: 1
Acties:
  • 262 views sinds 30-01-2008
  • Reageer

  • Lethalis
  • Registratie: April 2002
  • Niet online
Beste tweakers,

Ik ben een application server aan het schrijven die automatisch plugins moet kunnen detecteren en gegevens over gevonden applicaties in een assembly in een database moet opslaan.

Nu ben ik aan de slag gegaan met custom attributes en heb ik heel wat tutorials er op nageslagen, maar om de 1 of andere reden werkt het nog steeds niet.

Ik gebruik de volgende code om types en attributes te doorzoeken:

code:
1
2
3
4
5
6
7
8
9
10
11
12
Assembly asm = Assembly.LoadFrom(fullPath);

Type [] typesInAssembly = asm.GetTypes();
foreach (Type type in typesInAssembly)
{
    Trace.TraceInformation("Found type : {0}", type.FullName);
    
    foreach (Object customAttr in type.GetCustomAttributes(false))
    {
        Trace.TraceInformation("Found custom attribute : {0}", customAttr.GetType().FullName);
    }
}


Dit schijnt prima te werken en ik krijg netjes een lijstje terug. Echter, als ik nu gegevens uit een attribute wil lezen door hem te casten gaat het fout.

Als ik bijv. een custom attribute heb dat PluginInfo heet, dan geeft de volgende code een fout:

PluginInfo info = (PluginInfo)customAttr;

De fout die ik krijg is dan: Unable to cast object of type 'AppLib.PluginInfo' to type 'AppLib.PluginInfo'.

Eerst dacht ik dat het misschien kwam omdat het verschillende versies waren, maar na een hercompilatie van alles heb ik dat uitgesloten. Als ik op internet zoek naar tutorials over hoe ik custom attributes uit een assembly moet lezen, doen ze het op dezelfde manier als ik :|

Voorbeeld:
http://www.devx.com/codemag/Article/16706/0/page/4

Iemand enig idee naar wat ik moet kijken? :+

Bij voorbaat dank :)

Ask yourself if you are happy and then you cease to be.


  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

persoonlijk vind ik het beter en gemakkelijker om voor plugins interfaces te gebruiken.
Dan kun je gewoon van het type opvragen of het jouw interface implementeert. Dit geeft je bovendien een houvast over wat kan en niet kan. Ik kan namelijk elke klasse het PluginInfo attribuut geven, maar de interface kan zo verschillen dat je geen houvast hebt over hoe je de plugin moet gebruiken.

overigens is jouw methode voor zover ik kan zien correct.
Misschien kun je eens proberen om typeof(PluginInfo) en customAttr.GetType() te vergelijken.

ASSUME makes an ASS out of U and ME


  • Lethalis
  • Registratie: April 2002
  • Niet online
HIGHGuY schreef op donderdag 23 februari 2006 @ 14:02:
persoonlijk vind ik het beter en gemakkelijker om voor plugins interfaces te gebruiken.
Dan kun je gewoon van het type opvragen of het jouw interface implementeert. Dit geeft je bovendien een houvast over wat kan en niet kan. Ik kan namelijk elke klasse het PluginInfo attribuut geven, maar de interface kan zo verschillen dat je geen houvast hebt over hoe je de plugin moet gebruiken.

overigens is jouw methode voor zover ik kan zien correct.
Misschien kun je eens proberen om typeof(PluginInfo) en customAttr.GetType() te vergelijken.
Ik gebruik uiteraard een interface om de applicaties uit te voeren, maar wil custom attributes gebruiken om gegevens over de applicaties uit te lezen :)

Voorbeeldimplementatie van applicatie in plugin:
code:
1
2
3
4
5
6
7
8
9
10
11
12
[PluginInfo("TestApp", "This is a test application!")]
public class TestApp : MarshalByRefObject, IPluginApplication
{
    #region IPluginApplication Members
    
    public void HandleEvent(PluginEvent e)
    {
        // Code here
    }
    
    #endregion
}


Het idee is dat ik de gegevens die ik via PluginInfo doorgeef, kan inlezen en gebruiken in de applicatie server.

[ Voor 23% gewijzigd door Lethalis op 23-02-2006 14:10 ]

Ask yourself if you are happy and then you cease to be.


  • MTWZZ
  • Registratie: Mei 2000
  • Laatst online: 13-08-2021

MTWZZ

One life, live it!

proberen met het is keyword?
zoiets:
C#:
1
2
3
if(customAttr is PluginInfo) {
    PluginInfo info = (PluginInfo)customAttr;
}

Nu met Land Rover Series 3 en Defender 90


  • Lethalis
  • Registratie: April 2002
  • Niet online
MTWZZ schreef op donderdag 23 februari 2006 @ 14:07:
proberen met het is keyword?
zoiets:
C#:
1
2
3
if(customAttr is PluginInfo) {
    PluginInfo info = (PluginInfo)customAttr;
}
Heb ik al geprobeerd en dan vindt hij hem dus ook niet.. maar het is gewoon hetzelfde type :/

Ask yourself if you are happy and then you cease to be.


  • MTWZZ
  • Registratie: Mei 2000
  • Laatst online: 13-08-2021

MTWZZ

One life, live it!

Oh ja :/

En zo:
C#:
1
2
3
4
5
6
object[ ] laAttributes = 
       loType.GetCustomAttributes( 
       typeof( PluginInfo ), 
       false ) ;

// <-- meuk die je al had -->

Nu met Land Rover Series 3 en Defender 90


  • Lethalis
  • Registratie: April 2002
  • Niet online
MTWZZ schreef op donderdag 23 februari 2006 @ 14:12:
Oh ja :/

En zo:
C#:
1
2
3
4
5
6
object[ ] laAttributes = 
       loType.GetCustomAttributes( 
       typeof( PluginInfo ), 
       false ) ;

// <-- meuk die je al had -->
Ook al geprobeerd :D En ook zonder resultaat :Y)

Ask yourself if you are happy and then you cease to be.


  • Lethalis
  • Registratie: April 2002
  • Niet online
Simpele oplossing is misschien methods in de interface te declareren die de benodigde informatie terug geven. Maar ik kan er niet echt tegen dat die custom attributes in dit geval niet werken ;)

Wat zijn eigenlijk de voor- en nadelen m.b.t. het gebruik van Custom Attributes vs. methods in de interface?

Bijv. het gebruik van GetDescription t.o.v. een Custom Attribute dat de Description bevat?

Ask yourself if you are happy and then you cease to be.


  • MTWZZ
  • Registratie: Mei 2000
  • Laatst online: 13-08-2021

MTWZZ

One life, live it!

Tsja je zou custom attributes eventueel kunnen gebruiken voor licentie zaken hoewel dat ook niet echt de meest praktische methode is.
Misschien dat er handige dingen te doen zjin met attributes maar die zie ik zo 1, 2 3 niet :P

Nu met Land Rover Series 3 en Defender 90


  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

heb je die typeof(PluginInfo) en customAttr.GetType() al eens in de debugger vergeleken ?

ASSUME makes an ASS out of U and ME


  • mulder
  • Registratie: Augustus 2001
  • Laatst online: 23:22

mulder

ik spuug op het trottoir

Misschien dat er handige dingen te doen zjin met attributes maar die zie ik zo 1, 2 3 niet
Custom attributes zijn te gebruiken als metadata. (en dus heel handig)
Bijv. het gebruik van GetDescription t.o.v. een Custom Attribute dat de Description bevat?
Is dat eigenlijk niet hetzelfde?

oogjes open, snaveltjes dicht


  • Gerco
  • Registratie: Mei 2000
  • Laatst online: 28-03 23:48

Gerco

Professional Newbie

Weet je zeker dat het ook echt hetzelfde type is? Misschien heten ze alleen hetzelfde, maar zijn ze het niet. Geef de assembly die de type PluginInfo bevat een strong name en reference deze dan vanuit de plugin, dan weet je iig zeker dat je het over hetzelfde Type hebt.

- "Als ik zou willen dat je het begreep, legde ik het wel beter uit!" | All number systems are base 10!


  • Lethalis
  • Registratie: April 2002
  • Niet online
Don Facundo schreef op donderdag 23 februari 2006 @ 14:34:
[...]
Is dat eigenlijk niet hetzelfde?
Het komt wel op hetzelfde neer ja, daarom zie ik het ook als optie ;)

Voelt alleen zwak :o uitwijken voor een probleem om het alsnog op een andere manier aan de praat te krijgen. Ik ga het vandaag nog proberen, maar morgen moet het maar.. de deadline weegt toch net even wat zwaarder :X

Ask yourself if you are happy and then you cease to be.


  • Lethalis
  • Registratie: April 2002
  • Niet online
HIGHGuY schreef op donderdag 23 februari 2006 @ 14:32:
heb je die typeof(PluginInfo) en customAttr.GetType() al eens in de debugger vergeleken ?
Yup, ik ben nu alle velden aan het doorlopen want ze lijken hetzelfde te zijn, maar als ik typeof(PluginInfo) == customAttr.GetType() in de QuickWatch invoer, dan krijg ik false terug.

FullName en versie is gelijk.. dus het wordt even zoeken :X

[edit]
Qualified name is dus hetzelfde: AppLib.PluginInfo, AppLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null

[ Voor 13% gewijzigd door Lethalis op 23-02-2006 16:30 ]

Ask yourself if you are happy and then you cease to be.


  • Lethalis
  • Registratie: April 2002
  • Niet online
Argh, probleem opgelost.. Assembly.Codebase was verschillend. Het komt omdat ik de plugins uit een andere folder probeer te laden en Visual Studio daar automatisch een kopie van AppLib.dll heeft geplaatst.

Kwestie van AppLib in de GAC zetten dus :o (hoewel ik niet zeker weet of ik dat wel wil)

Bedankt voor jullie hulp :)

Rest de vraag om misschien toch voor methods te kiezen, alleen al vanwege de flexibiliteit.

[ Voor 23% gewijzigd door Lethalis op 23-02-2006 16:51 ]

Ask yourself if you are happy and then you cease to be.


  • Vedett.
  • Registratie: November 2005
  • Laatst online: 07:28
Ik zou zeker niet voor methods kiezen.
Ik zie een method als een verantwoordelijkheid van een class. En een beetje info ophalen van die class is daar zeker niet de bedoeling van.

Daar zijn juist de attributen voor geschikt.


Heb je nu al eens geprobeerd om je assemblies te signen met dezelfde key? Zie Gerko
Ik veronderstel dat dit je probleem is.

-> Is maar een idee, heb nog nooit een plug in systeem gemaakt

  • Lethalis
  • Registratie: April 2002
  • Niet online
Vedett. schreef op donderdag 23 februari 2006 @ 20:16:
Heb je nu al eens geprobeerd om je assemblies te signen met dezelfde key? Zie Gerko
Ik veronderstel dat dit je probleem is.

-> Is maar een idee, heb nog nooit een plug in systeem gemaakt
Dat alleen werkt ook niet. Ik heb de AppLib assembly nu een strong name gegeven en in de GAC gezet.. nu werkt het als een zonnetje :)

Ask yourself if you are happy and then you cease to be.

Pagina: 1