上一篇我们已经可以获取各种FileHandler的实例和对应的元数据。本篇,我们做一个稍微完整的文件管理器。
1、修改接口IFileHandler,传入文件名
namespace IPart{ public interface IFileHandler { void Process(string fileName); }}
2、修改具体的FileHandler。
using IPart;using System;using System.ComponentModel.Composition;namespace Parts{ [Export(typeof(IFileHandler))]//表示此类需要导出,导出的类型为IFileHandler [ExportMetadata("Extension", ".txt")]//添加导出元数据Extension,值为.txt public class TxtFileHandler : IFileHandler { public void Process(string fileName) { Console.WriteLine("处理文本文件"+fileName); } }}
3、修改主函数
using IPart;using System;using System.ComponentModel.Composition.Hosting;using System.Linq;namespace meftest{ class Program { //容器,装东西用的。具体装什么先不管。 private static CompositionContainer container; static void Main(string[] args) { //模拟数据。 string[] files = new string[] { @"c:\xxoo\xxoo.txt", @"c:\xxoo\ooxx.doc", @"d:\测试目录\mm.jpg", @"e:\电影\天海翼.avi", }; //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类型元数据,并且元数据的名字为Extension的实例)。 foreach (var file in files) { string ext = System.IO.Path.GetExtension(file).ToLower(); var export = exports.SingleOrDefault(o => o.Metadata.Extension == ext);//根据扩展名,也就是元数据来找到对应的处理实例,如果你找到了多个,会thow一个错误。 if (export != null) export.Value.Process(file); } Console.ReadLine(); } }}
运行结果:
可以看到,对每一个具体的文件,均找到了正确的处理实例进行处理。avi文件,没有找到处理的实例,就没处理。
扩展:
现在要能处理avi,非常的简单,随便拷贝一个Handler,实现Avi文件的处理逻辑即可,当然你仍然需要拷贝dll。
using IPart;using System;using System.ComponentModel.Composition;namespace Parts{ [Export(typeof(IFileHandler))]//表示此类需要导出,导出的类型为IFileHandler [ExportMetadata("Extension", ".avi")]//添加导出元数据Extension,值为.txt public class AviFileHandler : IFileHandler { public void Process(string fileName) { Console.WriteLine("播放av文件"+fileName); } }}
你看,扩展是不是很简单,只需要实现处理逻辑,主程序就可以多处理一种文件类型了。接口和主程序根本就不需要做改动。
和其他IOC框架相比,MEF不需要配置文件,用attribute的方式来做配置,非常的清楚简洁。
总结:
你用了十分钟就能看完这个系列,把所有项目都建一遍跑完,也就花个把小时。现在,你得到了一个新技能MEF,而且达到了我的水平,哈哈。
本人很菜,学MEF,园子里的文章好像对我来说有点难,走了一些弯路,最终才搞明白一些。因此想写一个能讲简单清楚一点的入门教程,也不知道目标达到了没有。
告诉我,MEF,你入门了没有。
最恨天下文章一大抄,请不要转载。