問題
我的MEF代碼在運行時沒有正確更新程序集,從與DirectoryCatalog關聯的文件夾中更新程序集。插件在運行時加載成功,但是當我更新dll並在DirectoryCatalog上調用Refresh時,程序集沒有得到更新。背景
我正在構建一個具有MEF容器的dll,並使用DirectoryCatalog來查找本地插件文件夾。我目前從一個簡單的WinForm中調用這個dll,這是安裝到一個單獨的項目使用ShadowCopy,所以我可以覆蓋我的插件文件夾中的dll。我沒有使用FileWatcher來更新這個文件夾,而是公開一個調用DirectoryCatalog刷新的公共方法,所以我可以隨意更新程序集而不是自動更新。代碼
基類實例化MEF目錄和容器,並將其保存爲類變量引用訪問後
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();
}
} ...
這裏就是我試圖覆蓋插件。我的更新測試是將返回的響應輸出到一個文本框,我更改插件返回的字符串,重建並將其複製到插件文件夾中。但它不會更新正在運行的應用程序,直到我關閉並重新啓動應用程序。
[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;
}
}
編輯
import語句[ImportMany(AllowRecomposition=true)]
IEnumerable<Lazy<IPlugin, IPluginData>> plugins;
DirectoryCatalog.Refresh會沒有檢測到更新的assebmlies。只有新的或刪除的。看看這個答案解決方法和建議:http://stackoverflow.com/a/14842417/850119 – 2013-04-23 10:14:32
我的dll被鎖定時,他們被加載,所以我不能用新的dll覆蓋它們。你沒有這個問題嗎?你做了什麼讓他們可以更新。 – 2013-12-18 11:18:55
是的,我確實有這個問題。我提到的其中一個步驟是啓用「Shadow Copy」。陰影複製允許程序拉取dll程序集的本地副本,並將它們添加到本地緩存中,而不是鎖定dll。必須啓用此功能才能在運行時「熱插拔」dll,否則您需要停止該程序,更改dll,然後重新啓動它。我認爲這是我看的例子,但如果它不適合你谷歌MEF和影子副本,http://stackoverflow.com/questions/12593308/mef-and-shadowcopying-dlls-so-that-i -can-over-them-at-runtime – Madullah 2014-02-04 01:36:51