2010-02-07 8 views
5

ich eine Markierungsschnittstelle etwas wie diese:Gibt es eine schnellere/bessere Möglichkeit, Methoden zu erhalten, das Attribut angewandt in C#

[AttributeUsage(AttributeTargets.Method, AllowMultiple=false, Inherited=true)] 
public class MyAttribute : Attribute 
{ 
} 

Und ich will es Methoden, die auf verschiedene Klassen in verschiedenen Baugruppen anzuwenden. ..

Dann möchte ich eine MethodInfo für alle Methoden, die dieses Attribut angewendet haben. Ich muss die gesamte AppDomain durchsuchen und einen Verweis auf alle diese Methoden erhalten.

Ich weiß, wir können alle Arten bekommen und dann alle Methoden bekommen, aber gibt es eine schnellere/bessere Möglichkeit, dies zu tun? ... oder ist das die schnellste Art, die Informationen zu bekommen, die ich brauche?

(Ich bin mit ASP.NET MVC 1.0, C#, ./NET 3.5)

Dankhaufen!

Antwort

14

Schließlich, nein - Sie müssen sie scannen. LINQ macht es jedoch ziemlich schmerzfrei.

 var qry = from asm in AppDomain.CurrentDomain.GetAssemblies() 
        from type in asm.GetTypes() 
        from method in type.GetMethods() 
        where Attribute.IsDefined(method, typeof(MyAttribute)) 
        select method; 

Hinweis dies nur Scans geladen Baugruppen "wie es ist".

+0

Vielen Dank für das Marc! Und für die linq Abfrage ... und die Warnung ... Hilft mir und anderen auch ich bin mir sicher. Ich benutze ASP.NET MVC ... Ich testete Re: Class Laden in ASP.NET, weil ich festgestellt habe, dass einige meiner Unit-Tests keine externen Assemblys geladen, es sei denn, ein Typ wurde referenziert ... ASP.NET scheint zu Lade alles in die AppDomain zum Glück ... Danke nochmal. – jwwishart

0

Ich habe das auch vor ein paar Wochen gesucht. Ich denke, es gibt keinen leichteren Weg.
Sie könnten es vielleicht mit LINQ ein wenig verbessern.

+0

Das dachte ich auch! Danke – jwwishart

2

Eine Sache, die Sie beachten sollten, ist ein zusätzliches Attribut, das Sie auf eine Klasse/Struktur anwenden können, das anzeigt, dass null oder mehr Methoden dieses Typs markiert sind. Das sollte Ihnen mindestens eine Größenordnung der Leistung verbessern.

Wenn das Attribut benutzerdefiniert ist (nicht in das .NET-Framework integriert), sollten Sie bei der Aufzählung der Assemblys zum Abrufen der Typen Framework-Assemblys wie mscorlib und System überspringen.

+0

Danke für die Perf-Tipps! Ich würde abstimmen, wenn ich könnte ... – jwwishart

2

Wenn Sie wirklich die Leistungssteigerung benötigen, tun Sie als Marc suggested und dann die Ergebnisse in einer Datei zwischenspeichern. Wenn die Anwendung das nächste Mal geladen wird und die zwischengespeicherte Datei vorhanden ist, kann sie die entsprechende Methode laden, ohne jede Assembly zu analysieren.

Hier ist ein Beispiel für eine mögliche Cache-Datei:

<attributeCache> 

    <assembly name='Assembly1' filename='Assembly1.dll' timestamp='02/02/2010'> 
    <type name='Assembly1.Type1'> 
     <method name='Method1'/> 
    </type> 
    </assembly> 

<assembly name='Assembly2' filename='Assembly2.dll' timestamp='02/02/2010' /> 
</attributeCache>