在前面的文章中,几乎每一个示例咱们都会接触到扩展类的搜索位置,咱们也不妨想一下,既然是自动扩展,它确定会有一个或者多人可供查找的位置,否则MEF框架怎么知道哪里有扩展组件呢?数据库
就像咱们用导航系统去查找某个地方的全部旅店同样,正由于在该地的旅店已在数据库中注册了相关信息,咱们的导航系统才能查找到它,若是某家旅店没有向导航数据库提供任何数据,那很显然导航系统是没法识别到它的详细地址的。框架
MEF对扩展组件的查找范围一般有三个:函数
若是你还嫌不够的话,能够用AggregateCatalog来设置多个查找范围。布局
下面咱们来逐个尝试一下。测试
基于某个程序集的范围查找,最常干的是在当前程序集内查找,固然也能够在其余程序集中查找。只要能获得一个Assembly对象就能够在其中查找,你们都那么聪明,我相信你们能理解的。spa
下面是一个典型的作法,例子是在当前程序集中查找扩展部件的。3d
首先,咱们定义一个用于规范扩展部件行为的接口。orm
而后,写两个类来实现上面的接口,并将它们导出。对象
在应用程序类中,用一个公共字段把它们所有导入。blog
最后,在Main中进行组装并测试调用。
最终,程序运行结果以下图所示。
这一个咱们可能有些陌生,由于在前面文章的示例中,咱们并无使用过该类,可是,不要由于陌生而惧怕,天有多高,你的胆子就应该有多大,陌生的东西不少时候是不复杂的,就好像咱们与陌生人对话有时候反而比与熟人对话更自在。
DirectoryCatalog类能够指定一个目录,让MEF在这个目录下面寻找扩展组件,若是须要更细致的查找,能够在DirectoryCatalog类的构造函数中指定一个搜索字符串,这个字符串与咱们平时搜索文件同样,例如"ext_*",这代表只要以ext_开头的类库文件都在查找范围内。
这一次,咱们用一个WinForm应用程序来作例子,在窗体中咱们拖放几个控件,详见下图。
控件布局随意,我一贯主张个性化布局的,主要如下几个重要的控件得介绍一下:
名为txtDirec的TextBox用来显示选择的目录;名为cmbClass的ComboBox控件用来显示MEF发现的扩展类的列表,名为txtResult的TextBox显示扩展类的调用结果。
下面说一下本例的大概思路,咱们先把扩展的类库全放到一个任意文件夹下,而后在应用程序窗口上选择该目录后,让MEF框架在该目录下发现全部扩展类型并显示在ComboBox中。接着咱们从ComboBox中选择一个类来调用,并查看调用结果。
这个接口只有一个方法SaySomething,待会咱们分别用几个类来实现它,每一个类都独立写到一个类库中。
一样道理,再建两个类库项目,分别是ExtLibB和ExtLibC。
而后,咱们能够看看下面的执行结果。
有一天,我不当心把新的扩展类ExtLibD写到了WinForm项目中了,就像这样:
而后我想,若是能保留前面的三个扩展类的同时,也自动识别我写到WinForm项目中的扩展类,那该多好啊。不怕,.NET的强大只有你想不到,没有它作不到的。这时候我把目光投向AggregateCatalog类,利用它能够将多个搜索范围合并,咱们刚才的三个扩展是经过在一个文件夹中搜索的,而第四个扩展是写到WinForm项目中的,还记得前文中咱们说过AssemblyCatalog类,它能够在某个程序集中寻找扩展类,因此第四个扩展类咱们能够在WinForm项目所在的程序集中查找。
也就是说,咱们把AssemblyCatalog范围和DirectoryCatalog范围进行组合。因此,把前面button1_Click的代码改一下,变成如下这个样子:
用AggregateCatalog来把DirectoryCatalog和AssemblyCatalog合并起来,再传给CompositionContainer的构造函数,这样就能实现查找范围的组合了。
好,如今运行一下,看看第四个扩展是否是自动被发现了?
Good,预期的效果达到了,是否是很高兴呢,喝杯咖啡得意一下吧。
不知道你们看了我这几篇有关MEF的吹牛散文以后,会不会感叹MEF的神奇呢?无论你们会把MEF用在哪些地方,只要记住两个原则:
好了,说了这么多,我也口渴了,先喝杯橙汗解解渴,再见。