MEF入门之不求甚解,但力求简单能讲明白(四)

上一篇我们已经可以获取各种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:xxooxxoo.txt",
                @"c:xxooooxx.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>();//获得所有导出的部件(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,你入门了没有。

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

原文地址:https://www.cnblogs.com/luhuanong/p/5541264.html