In diesem Blog-Post möchte ich kurz erläutern, wie ich mit dem Problem des dynamischen Ladens von Assemblies umgegangen bin.

Vor einiger Zeit stand ich vor dem Problem, dass ich zur Laufzeit Assemblies austauschen wollte. Grund dafür war, dass ich eine Host-Applikation hatte, die Plug-Ins verwendet. Jetzt wollte ich bestehende Plug-Ins während der Laufzeit austauschen oder neue Plug-Ins hinzufügen ohne die Host-Applikation zu beenden. Dazu hatte ich ein Verzeichnis in dem sich, außer den Plug-Ins, alle Assemblies befanden. Die Plug-Ins selbst befanden sich in einem eigenen Unterverzeichnis. Selbst wenn die Plug-Ins von der Host-Applikation nicht mehr verwendet wurden, war es nicht möglich, diese Assemblies zu löschen.

Im Normalfall ist es so, dass sobald eine Assembly von einer Applikation verwendet wird, eine Referenz auf diese existiert. Diese Referenz wird leider erst gelöscht, wenn die ganze Applikation beendet wird.

Bei dem dynamischen Laden von Assemblies wird die zu ladende Assembly geöffnet, ausgelesen und dann geschlossen. Aus den ausgelesenen Bytes wird dann mittels Reflection eine Assembly im Arbeitsspeicher erzeugt. Auf die lokale Assembly hängt somit keine Referenz und es ist möglich diese zu löschen.

Meine Umsetzung sieht folgendermaßen aus:

    2 public IList<Plugin> GetPlugins(string assemblyName) {
    3     Assembly assembly;
    4     IList<Plugin> pluginList = new IList<Plugin>();
    5     try {
    6         byte[] byteAssembly = File.ReadAllBytes(assemblyName);
    7         assembly = Assembly.Load(byteAssembly);
    8     } catch (Exception ex) {
    9         log.Error(ex);
   10     }
   11     try {
   12         if (assembly != null) {
   13             Type[] assemblyTypes = assembly.GetTypes();
   14             foreach (Type assemblyTyp in assemblyTypes) {
   15                 if (typeof(Plugin).IsAssignableFrom(assemblyTyp)) {
   16                     plugin = (Plugin)assembly.CreateInstance(assemblyTyp
   17                                                                 .FullName);
   18                     if (plugin != null) {
   19                         pluginList.Add(plugin);
   20                     }
   21                 }
   22             }
   23         }
   24     } catch (ReflectionTypeLoadException ex) {
   25         log.Error(ex);
   26     }
   27     return pluginList;
   28 }
Leave a Reply