我正在使用MEF在我的应用中加载插件。一切正常,但我希望在将它们放入我的app文件夹时发现新的部分。这可能吗? 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);
}
}
答案 0 :(得分:21)
您可以使用FileSystemWatcher检测插件文件夹中删除的新DLL。然后,您可以通过调用DirectoryCatalog.Refresh
或AggregateCatalog.Catalogs.Add
来处理此类事件,以使用新部件更新MEF组合。
有些事情需要注意:
您需要将MEF导入标记为旨在处理重构,如Recomposition上的MEF编程指南部分所述。否则MEF会在您尝试更新时引发错误。
FileSystemWatcher
引发系统线程池线程上的事件(除非您使用SynchronizingObject
属性)。请注意,如果您从其他主题调用DirectoryCatalog.Refresh
,则必须构建CompositionContainer
并启用isThreadSafeFlag
。您还必须考虑在更新合成时将调用的属性设置器的线程安全性。
您还可以删除目录,方法是将它们从AggregateCatalog.Catalogs
集合中删除。但是没有办法卸载关联的程序集(除了卸载整个Appdomain
)。这也意味着在应用程序运行时仍无法删除或覆盖程序集。