在前面的文章中,几乎每个示例我们都会接触到扩展类的搜索位置,我们也不妨想一下,既然是自动扩展,它肯定会有一个或者多人可供查找的位置,不然MEF框架怎么知道哪里有扩展组件呢?

就像我们用导航系统去查找某个地方的所有旅店一样,正因为在该地的旅店已在数据库中注册了相关信息,我们的导航系统才能查找到它,如果某家旅店没有向导航数据库提供任何数据,那很显然导航系统是无法识别到它的详细地址的。

MEF对扩展组件的查找范围通常有三个:

  1. AssemblyCatalog:从某个程序集中查找。
  2. ApplicationCatalog:在应用程序所在的目录下查找。
  3. DirectoryCatalog:在某个目录下查找,如D:\\Libs。

如果你还嫌不够的话,可以用AggregateCatalog来设置多个查找范围。

下面我们来逐个尝试一下。

  1. AssemblyCatalog

基于某个程序集的范围查找,最常干的是在当前程序集内查找,当然也可以在其他程序集中查找。只要能得到一个Assembly对象就可以在其中查找,大家都那么聪明,我相信大家能理解的。

下面是一个典型的做法,例子是在当前程序集中查找扩展部件的。

首先,我们定义一个用于规范扩展部件行为的接口。

然后,写两个类来实现上面的接口,并将它们导出。

在应用程序类中,用一个公共字段把它们全部导入。

最后,在Main中进行组装并测试调用。

最终,程序运行结果如下图所示。

二、DirectoryCatalog

这一个我们可能有些陌生,因为在前面文章的示例中,我们并没有使用过该类,但是,不要因为陌生而害怕,天有多高,你的胆子就应该有多大,陌生的东西很多时候是不复杂的,就好像我们与陌生人对话有时候反而比与熟人对话更自在。

DirectoryCatalog类可以指定一个目录,让MEF在这个目录下面寻找扩展组件,如果需要更细致的查找,可以在DirectoryCatalog类的构造函数中指定一个搜索字符串,这个字符串与我们平时搜索文件一样,例如"ext_*",这表明只要以ext_开头的类库文件都在查找范围内。

这一次,我们用一个WinForm应用程序来做例子,在窗体中我们拖放几个控件,详见下图。

控件布局随意,我一向主张个性化布局的,主要以下几个重要的控件得介绍一下:

名为txtDirec的TextBox用来显示选择的目录;名为cmbClass的ComboBox控件用来显示MEF发现的扩展类的列表,名为txtResult的TextBox显示扩展类的调用结果。

下面说一下本例的大概思路,我们先把扩展的类库全放到一个任意文件夹下,然后在应用程序窗口上选择该目录后,让MEF框架在该目录下发现所有扩展类型并显示在ComboBox中。接着我们从ComboBox中选择一个类来调用,并查看调用结果。

  1. 我们先建一个公共类库,这个类库在主应用程序和所有扩展类库都会引用,因为我们会在其中定义用于规范组件行为的"宪法"(接口)。该类库暂名为CommonLib,代码如下,很简单,不超过10行。

这个接口只有一个方法SaySomething,待会我们分别用几个类来实现它,每个类都独立写到一个类库中。

  1. 新项一个类库项目,名为ExtLibA,代码如下:

同样道理,再建两个类库项目,分别是ExtLibB和ExtLibC。

  1. 分别生成这三个dll,还要包含一个CommonLib.dll,因为三个扩展库都引用了它。然后把这几个dll分别放到一个文件夹中,大致如下图所示。

  1. 回到WinForm项目,在窗体类中声明一个字段,公有或私有都无所谓,用于导入类型。

  1. 处理按钮事件,浏览目录,并从指定目录中寻找扩展部件,并且显示在ComboBox中。

  1. 处理按钮事件,调用ComoBox中选定的扩展类型。

然后,我们可以看看下面的执行结果。

三、AggregateCatalog

有一天,我不小心把新的扩展类ExtLibD写到了WinForm项目中了,就像这样:

然后我想,如果能保留前面的三个扩展类的同时,也自动识别我写到WinForm项目中的扩展类,那该多好啊。不怕,.NET的强大只有你想不到,没有它做不到的。这时候我把目光投向AggregateCatalog类,利用它可以将多个搜索范围合并,我们刚才的三个扩展是通过在一个文件夹中搜索的,而第四个扩展是写到WinForm项目中的,还记得前文中我们说过AssemblyCatalog类,它可以在某个程序集中寻找扩展类,所以第四个扩展类我们可以在WinForm项目所在的程序集中查找。

也就是说,我们把AssemblyCatalog范围和DirectoryCatalog范围进行组合。所以,把前面button1_Click的代码改一下,变成以下这个样子:

用AggregateCatalog来把DirectoryCatalog和AssemblyCatalog合并起来,再传给CompositionContainer的构造函数,这样就能实现查找范围的组合了。

好,现在运行一下,看看第四个扩展是不是自动被发现了?

Good,预期的效果达到了,是不是很高兴呢,喝杯咖啡得意一下吧。

不知道大家看了我这几篇有关MEF的吹牛散文之后,会不会感叹MEF的神奇呢?不管大家会把MEF用在哪些地方,只要记住两个原则:

  1. 在需要某项技术时就该当机立断,否则反受其乱。
  2. 技术运用讲求灵活,无招胜有招,就像李小龙的"李三脚"一样,切忌滥用。

好了,说了这么多,我也口渴了,先喝杯橙汗解解渴,再见。

实战MEF(4):搜索范围的更多相关文章

  1. 实战MEF(3):只导出类的成员

    通过前面两篇文章的介绍,相信各位会明白MEF中有不少实用价值.上一文中我们也讨论了导入与导出,对于导出导入,今天我们再深入一点点,嗯,只是深入一点点而已,不会很难的,请大家务必放心,如果大家觉得看文章 ...

  2. 实战MEF(2):导出&导入

    上一文中,我们大致明白了,利用MEF框架实现自动扫描并组装扩展组件的思路.本文我们继续前进,从最初的定义公共接口开始,一步步学会如何使用MEF. 在上一文中我们知道,对于每一个实现了公共规范的扩展组件 ...

  3. 实战MEF(1):一种不错的扩展方式

    在过去,我们完成一套应用程序后,如果后面对其功能进行了扩展或修整,往往需要重新编译代码生成新的应用程序,然后再覆盖原来的程序.这样的扩展方式对于较小的或者不经常扩展和更新的应用程序来说是可以接受的,而 ...

  4. 实战MEF(1)一种不错的扩展方式

    在过去,我们完成一套应用程序后,如果后面对其功能进行了扩展或修整,往往需要重新编译代码生成新的应用程序,然后再覆盖原来的程序.这样的扩展方式对于较小的或者不经常扩展和更新的应用程序来说是可以接受的,而 ...

  5. 实战MEF(5):导出元数据

    如何理解元数 我们可以把元数据理解为随类型一起导出的附加信息.有时候我们会考虑,把元数据随类型一并导出,增加一些说明,使得我们在导入的时候,可以多一些筛选条件. 默认的类型导出带有元数据吗 上面的内容 ...

  6. oracle 跨分区查询效率,Oracle分区表做跨分区查询

    问:有一张大表,其中按时间字段(TIME_ID)进行表分区(按季度分区),但是如果业务人员做跨季度的大批量数据的查询时,未能走TIME_ID分区索引,导致全表扫描.此种情况该如何处理? 示例解析: 1 ...

  7. MEF搜索范围

    MEF对扩展组件的查找范围通常有三个: AssemblyCatalog:从某个程序集中查找. ApplicationCatalog:在应用程序所在的目录下查找. DirectoryCatalog:在某 ...

  8. 【WPF】运用MEF实现窗口的动态扩展

    若干年前,老周写了几篇有关MEF的烂文,简单地说,MEF是一种动态扩展技术,比如可以指定以某个程序集或某个目录为搜索范围,应用程序在运行时会自动搜索符合条件的类型,并自动完成导入,这样做的好处是,主程 ...

  9. [.net 面向对象程序设计深入](26)实战设计模式——使用Ioc模式(控制反转或依赖注入)实现松散耦合设计(1)

    [.net 面向对象程序设计深入](26)实战设计模式——使用IoC模式(控制反转或依赖注入)实现松散耦合设计(1) 1,关于IOC模式 先看一些名词含义: IOC: Inversion of con ...

随机推荐

  1. Asia Hong Kong Regional Contest 2016

    A. Colourful Graph 可以在$2n$步之内实现交换任意两个点的颜色,然后就可以构造出方案. #include <bits/stdc++.h> using namespace ...

  2. sass sourcemap详细使用

    新发布的Sass 3.3版本,将Source Maps正式纳入了Sass中.这也成为Sass新版本的一大亮点,一大新功能.让广大Sass爱好者可以直接在浏览器中更容易调试自己的代码和Debug相关操作 ...

  3. label 多行显示自适应高度

    //项目中显示 地址:XXXXXXX换行  UILabel *numLable = [[UILabel alloc] initWithFrame:CGRectMake(80, 50, 40, 20)] ...

  4. div 添加滚动条

    <div id="dic" style="overflow:auto">

  5. markdown预览-快速入门

    最近要写文档,领导指定用markdown. 这个两三年前用过两次的神器工具,都忘的差不多了. 为了熟练一点这个技能,决定好好的重新学一次. 于是乎:看快速入门文档 ...30分钟...看完文档发现要来 ...

  6. SQl SGA 整理

    --查看诊断位置信息 select * from v$diag_info; --查看sga中内存分配信息 select * from sys.x$ksmfs; --查看内存块还剩余多少 select ...

  7. Django 搭建简易博客

    新增一个 APP 博客算是一个功能集,因此我们应将其体现为一个模块.这表现在 Django 应用里则是为其创建一个 APP Package.现在让 manage.py 中的 startapp 闪亮登场 ...

  8. C#时间戳转换

    ,,)).ToUniversalTime ().Ticks ) / ;//先取得当前的UTC时间,然后转换成计算用的周期数(简称计时周期数),每个周期为100纳钞(ns)=0.1微秒(us)=0.00 ...

  9. 游戏编程技巧 - Subclass Sandbox

    Subclass Sandbox 使用场景 你正在开发一款类似LOL的游戏,里面有许多英雄角色,你决定把这些英雄类交给小弟们实现.因为在这些英雄中,释放放技能时,有的要使用粒子系统造成炫酷的效果,有的 ...

  10. 多文档上传(upload multiple documents)功能不能使用怎么办?

    问题描述: 在SharePoint 2010的文档库里选择documents标签,然后选择upload document下拉菜单,你会发现upload multiple documents那个按钮是灰 ...