MEF运行时插件更新问题

时间:2013-04-22 15:19:19

标签: c# .net 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();
    }

} ...

这是我试图覆盖的插件。我对更新的测试是,返回的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具有完全相同的程序集名称时,Refresh方法不会更新程序集。对于我的POC,我刚刚测试了重建,并在程序集名称后附加了一个日期,其他一切都相同,它就像一个魅力。他们在下面评论中的链接非常有用,如果您遇到同样的问题,建议使用它们。

1 个答案:

答案 0 :(得分:3)

您是否已将AllowRecomposition参数设置为Import attribut?

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.

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