问题
我的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