Avatar billede carstensuurland Nybegynder
05. juli 2008 - 01:48 Der er 7 kommentarer og
1 løsning

Finde klasser via reflection og custom attributes

Hej Eksperter.

Håber på lidt hjælp til denne her.
Jeg skal loade alle tingængelige assemblies og derefter finde de klasser som implementerer en bestemt custom attribute.

Jeg har rammeværket på plads, men desværre finder jeg aldrig nogle klasser som har attributten på sig (underligt nok).

Min kode:

Selve attributten:
public class CompilerTypeAttribute : System.Attribute
{
    public readonly string Name;
    public CompilerTypeAttribute(string CompilerTagName)
    {
        Name = CompilerTagName;
    }
}

Klassen som har attributten:
[CompilerTypeAttribute("anchor")]
public class Anchor : TagCompiler
{
    public Anchor() { }
}

Rutinen der "enumer" assemblies (det er der den er gal)
public static TagCompiler GetCompiler(XmlNode Node){
  string[] dlls = System.IO.Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory + "bin\\", "*.dll");

  Type ctype = typeof(CompilerAttributes.CompilerTypeAttribute);

  foreach (string fileName in dlls)
  {
    Assembly thisAssembly = Assembly.LoadFile(fileName);
    foreach (Type CurrentType in thisAssembly.GetTypes())
    {
      // Hér får jeg altid nul attributes tilbage
      foreach(CompilerTypeAttribute att in Attribute.GetCustomAttributes(CurrentType, typeof(CompilerTypeAttribute))){
        System.Diagnostics.Debug.Print(att.Name);
      }
    }
  }
  //Dummy - Bare til test
  return null;
}

Kan du se hvad der er galt?
Avatar billede arne_v Ekspert
05. juli 2008 - 02:26 #1
Umiddelbart kan jeg ikke genskabe problemet.

Følgende virker fint hos mig:

using System;
using System.Reflection;

namespace E
{
    public class CompilerTypeAttribute : Attribute
    {
        public readonly string Name;
        public CompilerTypeAttribute(string CompilerTagName)
        {
            Name = CompilerTagName;
        }
    }
    [CompilerTypeAttribute("anchor")]
    public class Anchor
    {
        public Anchor() { }
    }
    public class Program
    {
        public static void Main(string[] args)
        {
            Assembly thisAssembly = Assembly.GetExecutingAssembly();
            foreach (Type CurrentType in thisAssembly.GetTypes())
            {
                foreach(CompilerTypeAttribute att in Attribute.GetCustomAttributes(CurrentType, typeof(CompilerTypeAttribute)))
                {
                    Console.WriteLine(att.Name);
                }
            }
            Console.ReadKey();
        }
    }
}
Avatar billede arne_v Ekspert
05. juli 2008 - 02:28 #2
Jeg kan forestille mig 2 mulige forklaringer:

1) assemblies er ikke blevet rebuildet ordentligt

2) du har mere end en CompilerTypeAttribute og du slår op med en af dem mens
  klasserne indeholder en anden
Avatar billede carstensuurland Nybegynder
05. juli 2008 - 11:01 #3
Hej Arne.
Endnu en gang er du der som en mis :-) Du er for sej!
Jeg prøver lige din kode af, så ser jeg hvad der sker.

Jeg mente nok, at min kode var korrekt... Måske ligger "fejlen" i, at jeg bruger en MSDN version af VS2008? Den opfører sig også lidt underligt på andre fronter. Samme med en VS2005 som også er hentet fra MSDN.

Jeg vender tilbage.
Avatar billede carstensuurland Nybegynder
05. juli 2008 - 11:13 #4
Hm... Lidt underligt.
Hvis jeg bruger .GetExecutingAssembly() så virker min kode, men hvis jeg loader en DLL via .LoadFile, så virker det ikke.
Avatar billede carstensuurland Nybegynder
05. juli 2008 - 11:26 #5
Endnu en gang hm...
Hvis jeg bruger LoadFrom istedet for LoadFile virker det også...
Det virker nu som jeg gene vil have det til - Arne: Giv et svar så får du pointene (glemente vist at sætte den til 200 som jeg plejer, men du svarer sikkert også på det bærste af mine spørgsmål, så point får du da :-) )
Avatar billede carstensuurland Nybegynder
05. juli 2008 - 11:26 #6
og undskyld for alle stavefejlene i det sidste indlæg
Avatar billede arne_v Ekspert
05. juli 2008 - 22:50 #7
Jeg tror altså at min mulige forklarting #2 er rigtig.

Docs siger:

Use the LoadFile method to load and examine assemblies that have the same identity, but are located in different paths. LoadFile does not load files into the LoadFrom context, and does not resolve dependencies using the load path, as the LoadFrom method does. LoadFile is useful in this limited scenario because LoadFrom cannot be used to load assemblies that have the same identities but different paths; it will load only the first such assembly.
Avatar billede arne_v Ekspert
05. juli 2008 - 22:50 #8
og et svar
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester