zoukankan      html  css  js  c++  java
  • 实战MEF(4):搜索范围

    在前面的文章中,几乎每个示例我们都会接触到扩展类的搜索位置,我们也不妨想一下,既然是自动扩展,它肯定会有一个或者多人可供查找的位置,不然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. 技术运用讲求灵活,无招胜有招,就像李小龙的"李三脚"一样,切忌滥用。

    文章转载:东邪独孤

  • 相关阅读:
    poj 3068 Bridge Across Islands
    XidianOJ 1086 Flappy v8
    XidianOJ 1036 分配宝藏
    XidianOJ 1090 爬树的V8
    XidianOJ 1088 AK后的V8
    XidianOJ 1062 Black King Bar
    XidianOJ 1091 看Dota视频的V8
    XidianOJ 1098 突击数论前的xry111
    XidianOJ 1019 自然数的秘密
    XidianOJ 1109 Too Naive
  • 原文地址:https://www.cnblogs.com/gzskys/p/5595533.html
Copyright © 2011-2022 走看看