我的另一个博客:http://seodashi.sinaapp.com/mef_autorefreshcatalog.html
概述
MEF总结起来就是从目录中把有导出的部件导入到容器中,再根据类型把容器中的东西取出来用。
目录类的继承关系
.net 4.5
System.Object
System.ComponentModel.Composition.Primitives.ComposablePartCatalog
System.ComponentModel.Composition.Hosting.AggregateCatalog
System.ComponentModel.Composition.Hosting.ApplicationCatalog
System.ComponentModel.Composition.Hosting.AssemblyCatalog
System.ComponentModel.Composition.Hosting.CompositionScopeDefinition
System.ComponentModel.Composition.Hosting.DirectoryCatalog
System.ComponentModel.Composition.Hosting.FilteredCatalog
System.ComponentModel.Composition.Hosting.TypeCatalog
.net 4.0
System.Object
System.ComponentModel.Composition.Primitives.ComposablePartCatalog
System.ComponentModel.Composition.Hosting.AggregateCatalog
System.ComponentModel.Composition.Hosting.AssemblyCatalog
System.ComponentModel.Composition.Hosting.DirectoryCatalog
System.ComponentModel.Composition.Hosting.TypeCatalog
.net 4.5里面的目录类型比.net 4.0多出了很多,可以查阅msdn。
需求场景
描述这样一种需求:有一个不能随便重启的程序使用MEF完成了插件机制,插件以dll的形式放在Add-Ins目录下,启动后从Add-Ins目录加载插件,然后在程序运行过程中,插件需要增加、更新、删除等操作,希望不重启程序但是又能用新的插件。
如果只使用MEF,会出现如下问题:
1.向Add-Ins目录增加插件A.dll,程序不会自动对此目录的改变做出响应,所以也就不能发现插件A.dll。
2.删除和更新Add-Ins目录下插件B.dll,会报出“文件正在被其他进程使用,不能删除”。
解决方案
首先我们要解决第一个问题,增加一类自动刷新的目录。
public class AutoRefreshDirectoryCatalog : DirectoryCatalog
{
public bool NotifyOnDirectoryChanged { get; private set; }
public AutoRefreshDirectoryCatalog(string path)
: this(path, false)
{ }
public AutoRefreshDirectoryCatalog(string path,
bool notifyOnDirectoryChanged)
: base(path)
{
this.NotifyOnDirectoryChanged = notifyOnDirectoryChanged;
if (notifyOnDirectoryChanged)
{
FileSystemWatcher fsw = new FileSystemWatcher(path, "*.dll");
fsw.EnableRaisingEvents = true;
fsw.Created += (s, e) => {Refresh();};
fsw.Changed += (s, e) => {Refresh();};
fsw.Deleted += (s, e) => {Refresh();};
}
}
}
下一篇将会解决第二个问题。
参考资料:
【1】http://msdn.microsoft.com/zh-cn/library/system.componentmodel.composition.primitives.composablepartcatalog%28v=vs.100%29.aspx
【2】http://www.silverlightwpf.fr/post/2010/09/08/MEF-et-DirectoryCatalog-Refresh.aspx