Archiv der Kategorie: Reflections

Laden von 64Bit DLLs in 32Bit Anwendung mit Reflection


Da könnte man sich fragen wozu man sowas braucht. Aber es gibt immer einen guten Grund und in meinem Fall ging es darum, das ich in einem T4 Template 64Bit DLLs laden musste und diese nach Benutzerdefinierten Attributen zu durchsuchen um dann eine passende Ausgabe zu erstellen. Leider gibt es die Konsolenanwendung mit der VisualStudio die T4 Templates ausführt nur als 32 Bit Anwendung, daher musste eine andere Lösung her und die hieß, laden von 64Bit DLLs in einer 32 Bit Anwendung.

Wenn man also 64Bit DLLs in einer 32Bit Anwendung laden möchte, kann man nicht mehr einfach Assembly.LoadFrom(“FilePathDll”) verwenden, was einem die passende DLL inklusive aller Abhängigkeiten lädt, sondern man muss Assembly.ReflectionOnlyLoadFrom(“FilePathDll”) verwenden. Diese Funktion lädt leider nicht mehr automatisch alle Abhängigkeiten, sondern diese muss man “manuell” nachladen. Dafür stellt .NET einen Eventhandler bereit AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve, an dem man einfach eine passende Funktion registrieren muss, die immer dann aufgerufen wird, wenn eine abhängige Assembly benötigt wird (aufgelöst werden muss) und die Funktion gibt die passende Assembly zurück.

Das Laden von Assemblies und der passende Eventhandler könnten dann z.B. im einfachsten Fall folgendermaßen implementiert werden

 

Ein weiterer “Vorteil” dieser Lösung (zumindest in meinem Fall),  das für alle Dateien die im übergebenen Verzeichnis aufgelöst werden können (NUR NACH NAME keine Versionsnummer), die Assembly Redirects ignoriert werden. Das gilt für alle DLLs die wir im Snippet mit Assembly.ReflectionOnlyLoadFrom(pathWithDll) aufrufen, da wir hier vorher kein ApplyPolicy anwenden. Das Problem bei T4 Templates ist nämlich, das es im Ausführungskontext von Visual Studio ausgeführt wird und damit nicht die Assembly Redirects z.B. aus der web.config oder der app.config im Projekt verwendet, sondern nur die Redirects die in der app.config des Visual Studios angegeben sind.

Ein weiterer und leider auch entscheidender Nachteil an dieser Lösung ist das man eigene Attribute nicht mehr so einfach suchen kann. Denn die Funktion GetCustomAttributes(…) kann nicht verwendet werden, wenn man Assembly.ReflectionOnlyLoadFrom verwendet. Hier steht einem nur die Methode GetCustomAttributesData() zur Verfügung, mit der das Filtern nach eigenen Attributen nicht mehr ganz so komfortabel ist.

Hinweis: Probleme hatte ich außerdem, beim Vergleichen von Typen

assembly.GetCustomAttributesData().Where(p => p.AttributeType == typeof(MeinAttribut))

hier haben die Hashcodes nicht übereingestimmt, obwohl es sich um das gleiche Attribut/Typen handelte, daher habe ich dann nach FullName verglichen und das hat dann funktioniert, hier weiß ich leider nicht woran das liegt.

assembly.GetCustomAttributesData().Where(p => p.AttributeType.FullName == typeof(MeinAttribut).FullName)

Quelle: http://blog.slaks.net/2013-12-25/redirecting-assembly-loads-at-runtime/

Advertisements

Coole Seite für Extension Methoden


Habe die Tage eine Coole Seite entdeckt, auf der die unterschiedlichsten Extension Methoden aufgelistet sind.

http://www.extensionmethod.net

aufmerksam geworden bin ich auf die Seite als ich eine Extension Methode für Listen gesucht habe um diese nach einem Bestimmten Wert zu sortieren, der z.B. bei MVC in der URL übergeben werden kann und für alle Objekttypen gültig ist. Mit Hilfe einer generischen Extension und Reflections war das dann alles kein Problem mehr.

http://www.extensionmethod.net/Details.aspx?ID=124