2009-02-11 13 views
5

Ich suche nach einer effizienteren Möglichkeit, einen Typ in einer Assembly zu finden, die von einem bekannten spezifischen Typ abgeleitet ist. Im Grunde habe ich eine Plugin-Architektur in meiner Anwendung, und für die längste Zeit, die wir haben das getan:Wie kann ich einen bestimmten Typ in einer Assembly * effizient finden *?

For Each t As Type In assem.GetTypes() 
    If t.BaseType Is pluginType Then 
     'Do Stuff here' 
    End If 
Next 

Einige der Plugins haben eine große Anzahl von Arten und wir beginnen, um zu sehen, das eine nehmen ein paar Sekunden. Gibt es eine Möglichkeit, nach allen Typen zu fragen, die einen BaseType von "pluginType" haben?

EDIT: Ich habe mein Codebeispiel zu stark vereinfacht. Ich habe .GetExportedTypes() in meinem tatsächlichen Code verwendet. Allerdings waren viele Klassen als "öffentlich" markiert, was nicht sehr hilfreich war. Ich habe die Projekte durchgekämmt und alles "Freund" markiert, mit Ausnahme der eigentlichen Plugin-Klasse, und es dauert immer noch fast die gleiche Zeit, um die Assemblys zu untersuchen. Ich schneide vielleicht 100 ms von 1,3 Sekunden (was weniger als 10% ist). Ist das nur die Mindestzeit, mit der ich mich auseinandersetzen muss? Ich habe auch den Assembly-Attribut-Vorschlag ausprobiert und es ergab immer noch keinen großen Unterschied (vielleicht wieder 100ms). Ist der Rest der Zeit der Overhead, den ich bezahlen muss, um Baugruppen dynamisch zu laden?

+0

Nicht wirklich eine Antwort auf die Frage, aber vielleicht einen Blick auf MEF: http: //www.codeplex.com/MEF – herskinduk

+0

Um wie viel komplexer ist Ihre reale Testbedingung? Verwenden Sie 'AndAlso' und' OrElse' oder nur 'And' und' Or'? Ich frage, weil auf meinem langsamsten Rechner mit dem DotLisp-Interpreter das Aufzählen von 14807-Typen 0,322 Sekunden dauert und das Abrufen von öffentlichen Typen mit "BaseType = Component" 0,458 Sekunden dauert. Oh, beim Überprüfen der kompilierten LinqPad-Version dieser Abfrage auf dieser langsameren Maschine sehe ich das Problem: Bevor die 'Type'-Objekte zwischengespeichert oder sogar hinter die Kulissen gebaut werden, ist es viel langsamer: 10961' Typen' in 10.206 Sekunden! Unmittelbar danach sind es nur noch 0,03323 Sekunden, um 'Components' zu finden. –

Antwort

1

Assembly.GetExportedTypes() gibt nur öffentliche Klassen zurück. Könnte das helfen?

+0

Bitte überprüfen Sie die aktualisierte Frage ... –

4

Als Erstes können Sie versuchen, GetExportedTypes() zu verwenden, um die Liste der möglichen Typen einzuschränken. Abgesehen davon können Sie den Iterationsprozess nicht beschleunigen. Sie können jedoch umfassen ein Plugin, das Mainfest den genauen Typ (Typen) von Plugins innerhalb einer bestimmten Assembly angeben würde:

<manifest> 
    <plugin type="FooBar.Plugins.BazPlugin, FooBar" /> 
</manifest> 

, so dass Sie in der Lage sein würde Type.GetType(string)

IPlugin plugin = (IPlugin)Type.GetType("manifest/plugin/@type" /* for the sake of this discussion */); 
+0

Bitte sehen Sie die aktualisierte Frage ... –

0

Unsere zu tun Plug-in-System verwendet Attribute, um die Plug-in-Typen zu identifizieren. Wir scannen dann einfach die Baugruppe nach dem spezifischen Attribut.

+0

Bitte sehen Sie die aktualisierte Frage ... –

1

Lösung von mono-devel mailing list post by Jonathan Pryor und Plug-in Framework (Part1): Marking Types for Consumption: verwenden Sie Attribute auf Baugruppenebene.

Kurz gesagt, würden Sie ein neues Attribut hinzu:

[AttributeUsage(AttributeTargets.Assembly, AllowMultiple=true)] 
class PluginAttribute : Attribute { 
    public PluginAttribute (Type type) {this.Type = type;} 
    public Type Type {get; private set;} 
} 

Dann dieses Attribut festlegen, auf Baugruppenebene:

[assembly:Plugin (typeof(Plugin1))] 
[assembly:Plugin (typeof(Plugin2))] 

Dann die Montage für alle PluginAttributes abfragen:

Assembly a = ...; 
PluginAttribute[] plugins = 
    (PluginAttribute[]) a.GetCustomAttributes (
     typeof(PluginAttribute), true); 
foreach (var plugin in plugins) 
// plugin.Type is the type to use as a plugin 

Dies kann erheblich schneller sein als mit Assembly.GetTypes()/Assembly.GetExportedTypes(), als nur die Typen, die in [assembly:Plugin] aufgeführt sind Attribute tatsächlich geladen werden müssen, die die Menge an Speicher verbraucht deutlich verringern kann (abhängig von der Anzahl der Typen in der Baugruppe).

0

Gegeben mein Kommentar zu der Frage, wenn Sie können alle Typen in einem anderen Thread aufzählen, während Sie andere Dinge tun. Dann, wenn Sie bereit sind, die Typen aufzulisten, die Sie benötigen, sollte es mindestens zwei Größenordnungen schneller sein, laut my tests.