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

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


上一篇我们已经获得了制定类型的实例,但我们还无法对其进行有效的控制。

我们用ExportMetadata属性可以对具体的某个实例做标记,相当于命名。这么理解不知道对否。

在IPart项目中添加一个接口IPatMetadata

namespace IPart{  public interface IPatMetadata  {    string Extension { get; }//以后缀名来区分,特别需要注意,这里的名称要和ExportMetadata里面的一致。  }}

在导出的地方添加具体的导出元数据ExportMetadata,以txtFileHandler为例

using IPart;using System;using System.ComponentModel.Composition;namespace Parts{  [Export(typeof(IFileHandler))]//表示此类需要导出,导出的类型为IFileHandler  [ExportMetadata("Ext",".txt")]//添加导出元数据Ext,值为.txt  public class TxtFileHandler : IFileHandler  {    public void Process()    {      Console.WriteLine("处理文本文件");    }  }}

导出加了元数据,导入、使用的时候就发生了一点小变化。

主函数:

using IPart;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<IFileHandler,IPatMetadata>();//获得所有导出的部件(IFileHandler,并且带有IPatMetadata类型元数据,并且元数据的名字为Extension的实例)。      foreach (var item in exports)      {        Console.WriteLine(item.Metadata.Extension); //此处已可以获取元数据
item.Value.Process();//此处已经可以调用IFileHandler.Process()了 } Console.ReadLine(); } }}

运行结果:

在本例中,我们已经可以取得所有的文件Handler和其对应的元数据,这样我们就可以用linq的形式有针对性的取得某个具体文件的所对应的实例来进行处理了。说的很绕口,不过,等你看到代码你就会说,太easy了。

下一篇我们将传入文件名变量,做一个较为完整的文件管理器。