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

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

这是我现在的代码:

public sealed class RevealerFactory { private static readonly Lazy lazy = new Lazy(() => new RevealerFactory()); public static RevealerFactory Instance { get { return lazy.Value; } } private FileSystemWatcher watcher; private RevealerFactory() { Initialize(); } [ImportMany(RequiredCreationPolicy = CreationPolicy.Shared)] private IEnumerable<Lazy> 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.RefreshAggregateCatalog.Catalogs.Add来处理此类事件,以使用新部件更新MEF组合。

有些事情要注意:

  1. 您需要将MEF导入标记为旨在处理重构,如MEF编程指南中有关重构的部分所述。 否则MEF会在您尝试更新时引发错误。

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

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