你的位置:首页 > ASP.net教程

[ASP.net教程]MEF入门之不求甚解,但力求简单能讲明白(一)


起因:工作需要针对不同类型的文件做不同的处理。打个比方,txt文件,直接打印,doc文件,直接发email,jpg文件,上传xxx相册站点。

其实这个问题在学习最基本的工厂模式的时候早已经解决了,稍有点面向对象基础的,都可以写出这样一个文件管理器。再有新类型文件处理的时候,只需要在加一个实现类,再在工厂里面加一个if判断,返回一个具体的处理实例即可,上层不必改动。

要干掉工厂里面的if,则必须要请出ioc容器了。MEF就是微软自家的托管可扩展框架,在这里被我用成了ioc容器,其他的功能,不求甚解。

我们先拿MEF练练手,再应用到具体的项目中。概念什么的先扔到一边。

新建一个控制台应用程序项目和一个类库项目,两个项目均引用MEF库。类库项目中新建三个类文件。

using System;using System.ComponentModel.Composition;namespace Parts{  [Export(typeof(object))]//表示此类需要导出,导出的类型为object  public class TxtFileHandler  {    public void Process()    {      Console.WriteLine("处理文本文件");    }  }}

 其余的就不贴了,只是类名和输出语句不同。

 主程序:

using System;using System.ComponentModel.Composition.Hosting;namespace meftest{  class Program  {    //容器,装东西用的。具体装什么先不管。    private static CompositionContainer container;    static void Main(string[] args)    {      //AssemblyCatalog 目录的一种,表示在程序集中搜索      var assemblyCatalog = new AssemblyCatalog(typeof(Program).Assembly);//此处这一句实际上没啥用,因为此程序集下没有任何我们需要的实例(各种handler)      //在某个目录下的dll中搜索。      var directoryCatalog = new DirectoryCatalog(AppDomain.CurrentDomain.BaseDirectory,"*.dll");      var aggregateCatalog = new AggregateCatalog(assemblyCatalog, directoryCatalog);      //创建搜索到的部件,放到容器中。      container = new CompositionContainer(aggregateCatalog);          var exports = container.GetExports<object>();//获得所有导出的部件(object类型的)。      foreach (var item in exports)      {        Console.WriteLine(item.Value);      }      Console.ReadLine();    }  }}

编译两个项目,将生成的类库文件Parts.dll拷贝到主程序的bin\debug文件夹

  运行主程序:

可以看到,打印出了类名(object.ToString())。我们已经成功的创建了三个类的实例,但主程序并没有引用这个类库。

也可以说,我们将类的实例成功的注入到了主程序。

从这个小例子,我们可以学到,使用MEF三步骤:1、导出所需的类型(部件),2、在合适的目录(AssemblyCatalog、DirectoryCatalog)中查找。3、将找到的部件加入到容器。

之后你就可以使用容器中的已经New好的实例了。

注意:

在TxtFileHandler这个类上面的标记[Export(typeof(object))],表示此类需要导出,而且导出的类型为object

在main函数中,var exports = container.GetExports<object>();//获得所有导出的部件(object类型的)。

导出的类型和要获得的类型必须一致,这种一致性被称作为契约。

最恨天下文章一大抄,请不要转载。