Habt ihr schon einmal das Problem gehabt, dass ihr im laufenden Programm Assemblies eines anderen Programmes nachladen wollt? Evtl. eine API, die bereits vorher in einem anderen Verzeichnis installiert wurde? Es gibt dafür drei Möglichkeiten:
- Kopieren der benötigten Assemblies in der Zielordner der Anwendung
- Installation der Assemblies in den GAC (Global Assembly Cache)
- Einbinden eines eigenen ResourceEventHandler, der die Assemblies aus einem entsprechenden Verzeichnis lädt
Hier soll es um die letzte Möglichkeit gehen. In der Klasse AppDomain kann man über das statische Property CurrentDomain die aktuelle Application Domain des laufenden Programmes abfragen. In diesem Objekt kann man dann einen ResolveEventHandler unter AssemblyResolve registrieren, der dann das Laden der Assemblies übernimmt. Hört sich kompliziert an, ist es aber letztendlich nicht. Nachfolgendes Beispiel zeigt, wie man einen ResolveEventHandler registriert und wie der EventHandler aufgebaut ist. Dabei wird beim Registrieren der Pfad aus der Registry ausgelesen:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Text; using Microsoft.Win32; namespace ResourceEventLoader { public class ResourceLoader { public string Folder { get; private set; } public ResourceLoader() { } public void RegisterResourceEventHandler() { //retrieve folder from registry var folder = Registry.GetValue(@"REGISTRY_KEY_OF_YOUR_PATH", null, null); if (folder is string) { Folder = (string) folder; } AppDomain currentDomain = AppDomain.CurrentDomain; currentDomain.AssemblyResolve += MyResolveEventHandler; } public void DeregisterResourceEventHandler() { AppDomain currentDomain = AppDomain.CurrentDomain; currentDomain.AssemblyResolve -= MyResolveEventHandler; } private Assembly MyResolveEventHandler(object sender, ResolveEventArgs args) { string assemblyPath = Path.Combine(Folder, new AssemblyName(args.Name).Name + ".dll"); if (File.Exists(assemblyPath) == false) return null; Assembly assembly = Assembly.LoadFrom(assemblyPath); return assembly; } } } |