如何在应用程序运行时发现新的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.Refresh
或AggregateCatalog.Catalogs.Add
来处理此类事件,以使用新部件更新MEF组合。
有些事情要注意:
-
您需要将MEF导入标记为旨在处理重构,如MEF编程指南中有关重构的部分所述。 否则MEF会在您尝试更新时引发错误。
-
FileSystemWatcher
在系统线程池线程上引发事件(除非您使用SynchronizingObject
属性)。 请注意,如果从另一个线程调用DirectoryCatalog.Refresh
,则必须构造具有isThreadSafeFlag
的CompositionContainer
。 您还必须考虑在更新合成时将调用的属性设置器的线程安全性。 -
您还可以通过从
AggregateCatalog.Catalogs
集合中取出目录来删除目录。 但是没有办法卸载关联的程序集(除非卸载整个Appdomain
)。 这也意味着在应用程序运行时仍无法删除或覆盖程序集。