MEF-Laufzeitplugin-Update Problem
Problem
Mein MEF-Code aktualisiert Assemblys während der Laufzeit nicht ordnungsgemäß aus einem Ordner, der einem DirectoryCatalog zugeordnet ist. Die Plugins werden zur Laufzeit erfolgreich geladen, aber wenn ich die DLL aktualisiere und Refresh im DirectoryCatalog anrufe, werden die Assemblys nicht aktualisiert.Hintergrund
Ich baue eine DLL, die einen MEF-Container hat, und verwendet ein DirectoryCatalog, um einen lokalen Plugin-Ordner zu finden. Ich rufe diese DLL derzeit aus einem einfachen WinForm, das ist mit einem separaten Projekt, um ShadowCopy zu verwenden, so dass ich die DLLs in meinem Plugin-Ordner überschreiben kann. Anstatt einen FileWatcher zu verwenden, um diesen Ordner zu aktualisieren, mache ich eine öffentliche Methode verfügbar, die eine Aktualisierung im DirectoryCatalog aufruft, sodass ich die Assemblies nach Belieben aktualisieren kann, anstatt automatisch.-Code
Basisklasse instanziiert die MEF Kataloge und Behälter, und speichert sie als Klassenvariablen für Referenz Zugriff später
public class FieldProcessor
{
private CompositionContainer _container;
private DirectoryCatalog dirCatalog;
public FieldProcessor()
{
var catalog = new AggregateCatalog();
//Adds all the parts found in the same assembly as the TestPlugin class
catalog.Catalogs.Add(new AssemblyCatalog(typeof(TestPlugin).Assembly));
dirCatalog = new DirectoryCatalog(AppDomain.CurrentDomain.BaseDirectory + "Plugin\\");
catalog.Catalogs.Add(dirCatalog);
//Create the CompositionContainer with the parts in the catalog
_container = new CompositionContainer(catalog);
}
public void refreshCatalog()
{
dirCatalog.Refresh();
}
} ...
hier ist das Plugin ich versuche, zu überschreiben. Mein Test der Aktualisierung ist, dass die zurückgegebenen Stiche in ein Textfeld ausgegeben werden. Ich ändere die Strings, die das Plugin zurückgibt, neu erstellen und in den Plugin-Ordner kopieren. Aber es wird nicht für die laufende App aktualisiert, bis ich die App schließe und neu starte.
[Export(typeof(IPlugin))]
[ExportMetadata("PluginName", "TestPlugin2")]
public class TestPlugin2 : IPlugin
{
public IEnumerable<IField> GetFields(ContextObject contextObject, params string[] parameters)
{
List<IField> retList = new List<IField>();
//Do Work Return Wrok Results
retList.Add(new Field("plugin.TestPlugin2", "TestPluginReturnValue2"));
return retList;
}
}
bearbeiten
Import Statement[ImportMany(AllowRecomposition=true)]
IEnumerable<Lazy<IPlugin, IPluginData>> plugins;
DirectoryCatalog.Refresh wird aktualisierte Aufbauten nicht erkennen. Nur neue oder gelöschte. Werfen Sie einen Blick auf diese Antwort für eine Problemumgehung und Vorschläge: http://StackOverflow.com/a/14842417/850119 –
Meine DLLs sind gesperrt, wenn sie geladen sind, so kann ich sie mit neuen DLLs überschreiben. Hattest du dieses Problem nicht? hast du etwas gemacht, das sie aktualisierbar gemacht hat? –
Ja, ich hatte dieses Problem. Einer der Schritte, die ich im Vorbeigehen erwähnte, war "Schattenkopie". Mit Shadow Copy kann ein Programm lokale Kopien von DLL-Assemblys erstellen und sie einem lokalen Cache hinzufügen, anstatt die DLLs zu sperren. Dies muss aktiviert sein, damit Sie während der Laufzeit dlls "hot swap" austauschen können. Andernfalls müssen Sie das Programm stoppen, die dlls ändern und es dann neu starten. Ich denke, das ist das Beispiel, das ich angeschaut habe, aber wenn es für dich nicht funktioniert, google MEF und Shadow Copy, http://stackoverflow.com/questions/12593308/mef-and-shadowcopying-dlls-so-that-i -can-overwrite-them-at-runtime – Madullah