Wie kann ich mit Modulen mit verschiedenen Versionen der gleichen Abhängigkeiten in MEF umgehen?

9

Im Moment habe ich einen Modul-Ordner konfiguriert, und alle meine Modul-Assemblies und ihre Abhängigkeiten leben dort. Ich mache mir Sorgen, dass jemand in sechs Monaten ein neues Modul erstellt und seine Abhängigkeiten die älteren Versionen der Abhängigkeiten überschreiben.

Soll ich vielleicht eine Art Modulregistrierung entwickeln, bei der ein Entwickler ein neues Modul registriert und ihm im Ordner modules einen Unterordnernamen zuweist? Diese Art dämpft die Bequemlichkeit der Verwendung von DirectoryCatalog , wenn ich dem Host die Module mitteilen muss.

    
ProfK 28.01.2014, 07:17
quelle

1 Antwort

3

Ich hatte in der Vergangenheit ein ähnliches Problem. Im Folgenden stelle ich meine Lösung vor, die meiner Meinung nach ähnlich zu dem ist, was Sie erreichen möchten.

Das Verwenden von MEF ist wirklich faszinierend, aber hier sind meine Worte der Vorsicht:

  • Es wird schnell kompliziert
  • Sie müssen ein paar Kompromisse machen wie das Erben von MarshalByRefObject und Plugins, die nicht mit der Lösung
  • erstellt werden
  • Und, wie ich entschieden habe, ist einfacher besser! Andere Nicht-MEF-Designs könnten eine bessere Wahl sein.

Ok, Disclaimer aus dem Weg ...

Mit

.NET können Sie mehrere Versionen derselben Assembly in den Speicher laden, aber nicht entladen. Aus diesem Grund erfordert meine Vorgehensweise eine AppDomain, um das Entladen von Modulen zu ermöglichen, wenn eine neue Version verfügbar wird.

Die folgende Lösung ermöglicht das Kopieren von Plugin-DLLs in einen 'plugins' -Ordner im bin-Verzeichnis zur Laufzeit. Wenn neue Plugins hinzugefügt und alte überschrieben werden, wird das alte Plug-in entladen und das neue Plug-in wird geladen, ohne dass die Anwendung neu gestartet werden muss. Wenn Sie gleichzeitig mehrere DLLs mit verschiedenen Versionen in Ihrem Verzeichnis haben, möchten Sie möglicherweise PluginHost ändern, um die Assembly-Version über die Eigenschaften der Datei zu lesen und entsprechend zu agieren.

Es gibt drei Projekte:

  • ConsoleApplication.dll (nur References Integration.dll)
  • Integration.dll
  • TestPlugin.dll (References Integration.dll, muss in ConsoleApplication bin / Debug / plugins kopiert werden)

ConsoleApplication.dll

%Vor%

Integration.dll

PluginHost ermöglicht die Kommunikation mit Plugins. Es sollte immer nur eine Instanz von PluginHost geben. Dies dient auch als Abfrage DirectoryCatalog .

%Vor%

Autofac ist eine erforderliche Abhängigkeit dieses Codes. Der PluginDomainDependencyResolver wird in der Plugin-AppDomain instanziiert.

%Vor%

Diese Klasse repräsentiert die eigentliche Plugin AppDomain. Assemblys, die in diese Domäne aufgelöst werden, sollten zuerst alle Abhängigkeiten aus dem Ordner bin / plugins laden, gefolgt von dem Ordner bin, da es Teil der übergeordneten AppDomain ist.

%Vor%

Schließlich hat Ihr Plugin eine Schnittstelle.

%Vor%

Die Hauptanwendung muss über jedes Plugin Bescheid wissen, damit eine Schnittstelle benötigt wird. Sie müssen IPlugin erben und in der Methode PluginHost BuildContainer

registriert sein %Vor%

TestPlugin.dll

%Vor%

Abschließende Gedanken ...

Ein Grund, warum diese Lösung für mich funktionierte, ist, dass meine Plugin-Instanzen von der AppDomain eine sehr kurze Lebensdauer hatten. Ich glaube jedoch, dass Modifikationen vorgenommen werden könnten, um Plugin-Objekte mit einer längeren Lebensdauer zu unterstützen. Dies würde wahrscheinlich einige Kompromisse erfordern, wie zum Beispiel ein erweiterter Plugin-Wrapper, der das Objekt möglicherweise neu erstellen könnte, wenn die AppDomain neu geladen wird (siehe CallEach ).

    
sky-dev 28.02.2014 03:06
quelle

Tags und Links