• 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,你入门了没有。

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

  • 相关阅读:
    模块和包
    网络基础之网络协议
    计算机硬件知识
    面试题集锦(一)
    二分查找法
    ORM多表操作示例
    Django之URL(路由系统)用法
    用Nginx实现微信小程序本地SSL请求
    [PHP7.0-PHP7.2]的新特性和新变更
    利用Node的chokidar 监听文件改变的文件。
  • 原文地址:https://www.cnblogs.com/luhuanong/p/5541264.html
Copyright © 2020-2023  润新知