10

问题

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

背景

我正在构建一个具有 MEF 容器的 dll,并使用 DirectoryCatalog 来查找本地插件文件夹。我目前从一个简单的 WinForm 调用此 dll,该 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;
    }
}

编辑

进口声明

    [ImportMany(AllowRecomposition=true)]
    IEnumerable<Lazy<IPlugin, IPluginData>> plugins;

研究

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

要求

有没有人见过这个问题,或者知道是什么原因导致我的程序集在运行时没有更新?任何额外的信息或见解将不胜感激。

解析度

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

4

1 回答 1

3

did you set AllowRecomposition parameter to your 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

edit:

DirectoryCatalog doesn't update assemblies, only added or removed: http://msdn.microsoft.com/en-us/library/system.componentmodel.composition.hosting.directorycatalog.refresh.aspx

for a work around: https://stackoverflow.com/a/14842417/2215320

于 2013-04-22T20:58:33.670 回答