Wie man benutzerdefinierte Attribute aus einer assembly, die nicht (richtig) geladen
Wir alle wissen, dass die Baugruppe abgefragt werden können für Attribute mit der GetCustomAttributes-Methode. Ich möchte an dieser zu identifizieren, die eine Erweiterung Modul für meine Anwendung. Um jedoch zu vermeiden, laden jeden der Montage ziehe ich einen defensiven Ansatz:
-
mit Montage.ReflectionOnlyLoadFrom um mehr Informationen über eine assembly (hat es meine ModuleAttribute?)
-
wenn die ModuleAttribute gefunden wird, werde ich endlich laden Sie Sie, indem Sie Baugruppen.LoadFrom
Leider scheint es, dass es keine Möglichkeit gibt, um die Attribute einer assembly, die geladen wird in der Reflexion-nur Rahmen:
myAssembly.GetCustomAttributes(typeof(ModuleAttribute), false)
schlägt mit einer InvalidOperationException ("Es ist illegal zu reflektieren, die auf der benutzerdefinierten Attribute eines Typs geladen über ReflectionOnlyGetType") und
CustomAttributeData.GetCustomAttributes(myAssembly)
schlägt mit ReflectionTypeLoadException, weil der abhängigen Assemblys geladen wird.
So, wie man die Attribute ohne
- verschmutzen meine Anwendungsdomäne mit nutzlos (vielleicht schädlichen) Arten von aufrufenden Assembly.LoadFrom
- den laden müssen alle referenzierten Assemblys
- die Notwendigkeit für separate Anwendungsdomänen (gab es einen kurzen Versuch, Roch nach noch mehr PITA)
?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ist es möglich, zu laden (nur Reflexion) von Baugruppen mit Abhängigkeiten.
AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve +=
(s, e) => Assembly.ReflectionOnlyLoad(e.Name);
wäre fix Fehler beim laden, vorausgesetzt, Sie sind alle im selben Ordner.
ReflectionOnlyAssemblyResolve
- Ereignis ausgelöst wird. Sie können manuell laden Sie die assembly dann.Nach der Prüfung alle Antworten und einige weitere Forschung, es scheint, dass es einfach keinen Weg, das zu tun, was ich will: prüfen Sie, ob eine assembly ist eine gültige extension Modul vor dem laden in der Anwendungsdomäne.
Entweder habe ich um die assembly zu laden, die sollten überprüft werden, in eine andere Anwendungsdomäne, überprüfen es und wenn es gelingt, laden Sie es wieder in meine aktuelle Anwendungsdomäne ab, oder muss ich zum speichern von Metadaten der assembly außerhalb der Versammlung selbst, und Vertrauen Sie dieser Metadaten. Option eins ist nicht möglich aufgrund der architektonischen Einschränkungen, option zwei, nur verschiebt sich das problem aber nicht löst.
Wahrscheinlich die beste alternative ist die Verwendung des Managed Extensibility Framework, das ist aber leider nicht einfach in den aktuellen setup.
Habe ich am Ende darauf Vertrauen, dass es nichts "schlechtes" in das Module-Verzeichnis und laden alles (mit ein paar Prüfungen, für nicht mehr als eine maximale Datei-Größe und nicht bereits geladen).
Dennoch danke für deine Ideen.
Haben Sie schaute auf die microsoft Add-in-Framework.
Es ermöglicht das laden von Modulen (Add-ins) in den verschiedenen app-Domänen und-Prozesse, und die Abfrage-Schnittstelle auf bestimmte Attribut-Daten.
Könnte es nicht sein, was Sie wollen, aber könnte einen Blick Wert sein.
http://msdn.microsoft.com/en-us/library/bb384200.aspx
Und mit ein bisschen LINQ Abfragen kann es
Wirklich alte Frage, aber dies wurde möglich da .NET 2.0. Das problem ist, dass alles geladen wird in die Reflexion-nur load-Kontext implementiert ist, so dass Sie nicht versehentlich trigger laden der assembly in die aktuelle Anwendungsdomäne. Das reflektieren über das benutzerdefinierte Attribut-Typen in der assembly definiert ist einer von Ihnen.
Müssten Sie
CustomAttributeData
um diese benutzerdefinierte Attribute.CustomAttributeData
Instanzen enthalten die Informationen über die attribute, einschließlich Typ, Konstruktor, Parameter und benannte Parameter. Beachten Sie, dass die Arten in der Objekt-graph sind die Reflexion-nur, so, wenn Sie versuchen, Dinge zu tun mit Ihnen auslösen würde, dass das laden einer assembly, es werfe die bekannte Ausnahme.Können Sie diese Metadaten über Metadaten, um zu bestimmen, ob das reflektierte assembly qualifiziert sich für was auch immer Ihre Bedürfnisse sind.
Wenn ich Sie wäre würde ich den cache-assembly-Metadaten, z.B. über XML-Dateien. Mit diesem Ansatz sind Sie vollständig zu eliminieren die Notwendigkeit zu laden, nichts. Und können Sie speichern auch Informationen, zu berechnen, die Sie brauchen, um ein zeitaufwendiger Vorgang.
Können Sie XML-Dateien vorgenerierte oder generiert on-the-fly-by-Scannen Sie alle vorhandenen Baugruppen.
Wenn Sie remoting oder mit einer proxy-Konfiguration, haben Sie etwas ähnlich wie diese:
Jedoch, wenn Sie eine Ausnahme in der Domäne, es sieht wohl so:
Hier ist der code, der ausgelöst wird, dass aus der 1. Zeile.
Müssen Sie ändern, um es zu verwenden CustomAttributeData wie diese: