背景我建立一个具有MEF容器,并使用DirectoryCatalog找到当地的插件文件夹的DLL.我现在从一个简单的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(); } } ...
这是我试图覆盖的插件.我的更新测试是,返回的stings输出到一个文本框,我更改了插件返回,重建并将其复制到插件文件夹中的字符串.但是,对于正在运行的应用程序,它不会更新,直到我关闭并重新启动该应用程序.
[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; } }
编辑导入声明
[ImportMany(AllowRecomposition=true)] IEnumerable<Lazy<IPlugin,IPluginData>> plugins;
研究我在文章和代码示例中做了相当广泛的研究,答案似乎是,将DirectoryCatalog添加到容器并保存该目录的引用,然后在添加新插件后调用该引用的Refresh,它将更新组件…这我在做什么,但它没有显示更新的输出,来自新的插件DLL.
请求有没有人看到这个问题,或者知道在运行时没有更新程序集可能导致我的问题?任何其他信息或见解将不胜感激.
解决感谢Panos和Stumpy的链接,导致我的解决方案我的问题.对于未来的求知者,我的主要问题是,刷新方法不更新组件,当新的装配具有完全相同的组件名称作为覆盖DLL.对于我的POC我只是测试用附加到组件的名称和一切同一个日期重建,和它的工作就像一个魅力.他们在下面的评论中的链接非常有用,如果您有同样的问题,建议您使用.
解决方法
AllowRecomposition Gets or sets a value that indicates whether the property or field will be recomposed when exports with a matching contract have changed in the container.
编辑:
DirectoryCatalog不更新程序集,仅添加或删除:
http://msdn.microsoft.com/en-us/library/system.componentmodel.composition.hosting.directorycatalog.refresh.aspx