如何在应用程序运行时发现新的MEF部件

本文关键字:MEF 部件 发现 运行时 应用程序 | 更新日期: 2023-09-27 18:04:35

我使用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);
    }
}

如何在应用程序运行时发现新的MEF部件

您可以使用FileSystemWatcher来检测插件文件夹中正在删除的新dll。然后,您可以通过调用DirectoryCatalog.RefreshAggregateCatalog.Catalogs.Add来处理这些事件,以使用新部件更新MEF组合。

注意事项:

  1. 您需要将MEF导入标记为设计用于处理重组,如MEF编程指南中有关重组的部分所述。否则,当您尝试更新它们时,MEF将引发错误。

  2. FileSystemWatcher在系统线程池线程上引发事件(除非您使用SynchronizingObject属性)。请注意,如果从另一个线程调用DirectoryCatalog.Refresh,则必须在启用isThreadSafeFlag的情况下构造CompositionContainer。你还必须考虑在更新组合时将被调用的属性设置的线程安全性。

  3. 您还可以通过将AggregateCatalog.Catalogs集合中取出来删除目录。但是没有办法卸载相关的程序集(除非卸载整个Appdomain)。这也意味着当应用程序运行时,您仍然不能删除或覆盖程序集。