MEF运行时插件更新问题

Mab*_*lah 10 .net c# plugins mef updates

问题

我的MEF代码在运行时期间没有从与DirectoryCatalog关联的文件夹中正确更新程序集.插件在运行时成功加载,但是当我更新dll并在DirectoryCatalog上调用Refresh时,程序集不会更新.

背景

我正在构建一个具有MEF容器的DLL,并使用DirectoryCatalog查找本地插件文件夹.我现在从一个简单的WinForm调用这个dll,设置为使用一个单独的项目来使用ShadowCopy,这样我就可以覆盖插件文件夹中的dll.我没有使用FileWatcher更新此文件夹,而是公开了一个在DirectoryCatalog上调用refresh的公共方法,因此我可以随意更新程序集而不是自动更新程序集.

基类实例化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();
    }

} ...
Run Code Online (Sandbox Code Playgroud)

这是我试图覆盖的插件.我的更新测试是,返回的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;
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑

进口声明

    [ImportMany(AllowRecomposition=true)]
    IEnumerable<Lazy<IPlugin, IPluginData>> plugins;
Run Code Online (Sandbox Code Playgroud)

研究

我已经做了相当广泛的研究,在文章和代码示例的每个地方,答案似乎是,将DirectoryCatalog添加到容器并保存该目录的引用,然后在添加新插件后调用该引用上的Refresh,并且它将更新程序集...我正在做的,但它没有显示更新的输出,来自新的插件DLL.

请求

有没有人看过这个问题,或者知道什么可能导致我的问题,程序集在运行时没有更新?任何其他信息或见解将不胜感激.

解析度

感谢Panos和Stumpy的链接让我找到解决方案.对于未来的知识寻求者,我的主要问题是,当新程序集与覆盖的dll具有完全相同的程序集名称时,Refresh方法不会更新程序集.对于我的POC,我刚刚测试了重建,并在程序集名称后附加了一个日期,其他一切都相同,它就像一个魅力.他们在下面评论中的链接非常有用,如果您遇到同样的问题,建议使用它们.

小智 3

您是否AllowRecomposition为导入属性设置了参数?

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.
Run Code Online (Sandbox Code Playgroud)

http://msdn.microsoft.com/en-us/library/system.componentmodel.composition.importattribute(v=vs.95).aspx

编辑:

DirectoryCatalog 不更新程序集,仅添加或删除: http://msdn.microsoft.com/en-us/library/system.componentmodel.composition.hosting.directorycatalog.refresh.aspx

解决方法: https ://stackoverflow.com/a/14842417/2215320