我正在使用MEF在我的应用程序中加载插件。一切正常,但是当我将新部件放到我的应用程序文件夹中时,我希望它们能被发现。这可能吗? DirectoryCatalog有一个Changed事件,但是我不确定它是如何工作的。

这是我现在的代码:

public sealed class RevealerFactory
{
    private static readonly Lazy<RevealerFactory> lazy =
            new Lazy<RevealerFactory>(() => new RevealerFactory());

    public static RevealerFactory Instance { get { return lazy.Value; } }

    private FileSystemWatcher watcher;

    private RevealerFactory()
    {
        Initialize();
    }

    [ImportMany(RequiredCreationPolicy = CreationPolicy.Shared)]
    private IEnumerable<Lazy<IRevealer, IRevealerCapabilities>> Revealers {
        get;
        set;
    }

    public IRevealer GetRevealer(Uri uri)
    {
        return (from revealer in Revealers
                where uri.Host.Equals(revealer.Metadata.Host,
                                      StringComparison.OrdinalIgnoreCase)
                   && revealer.Value.IsRevelable(uri)
                select revealer.Value).FirstOrDefault();
    }

    private void Initialize()
    {
        var catalog = new DirectoryCatalog(
            Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
                                      + "/SDownloader/Revealers");
        var container = new CompositionContainer(catalog);
        container.ComposeParts(this);
    }
}

最佳答案

您可以使用FileSystemWatcher来检测在您的插件文件夹中删除的新DLL。然后,您可以通过调用 DirectoryCatalog.Refresh AggregateCatalog.Catalogs.Add 处理此类事件,以使用新部件更新MEF组成。

要注意的一些事情:

  • 您需要将MEF导入标记为旨在处理重组,如Recomposition上的MEF编程指南部分所述。否则,当您尝试更新它们时,MEF将引发错误。
  • FileSystemWatcher在系统线程池线程上引发事件(除非您使用 SynchronizingObject 属性)。请注意,如果从另一个线程调用DirectoryCatalog.Refresh,则必须在启用了CompositionContainer的情况下构造isThreadSafeFlag。您还必须考虑更新组合时将调用的属性 setter 的线程安全性。
  • 您还可以通过从AggregateCatalog.Catalogs集合中删除目录来删除目录。但是无法卸载关联的程序集(除非卸载整个Appdomain)。这也意味着在应用程序运行时,您仍然无法删除或覆盖程序集。
  • 10-04 15:16
    查看更多