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类型的)。
导出的类型和要获得的类型必须一致,这种一致性被称作为契约。
最恨天下文章一大抄,请不要转载。
MEF入门之不求甚解,但力求简单能讲明白(一)的更多相关文章
- MEF入门之不求甚解,但力求简单能讲明白(四)
上一篇我们已经可以获取各种FileHandler的实例和对应的元数据.本篇,我们做一个稍微完整的文件管理器. 1.修改接口IFileHandler,传入文件名 namespace IPart { pu ...
- MEF入门之不求甚解,但力求简单能讲明白(五)
我们已经成功的达到了目标,大量减少了if else. 不过在园子里面的文章大多,用的是Import.ImportMany.So,修改主函数. using IPart; using System; us ...
- MEF入门之不求甚解,但力求简单能讲明白(二)
在上一篇文章中,我们已经学到了很基本的MEF概念和使用方法. 但我们导出的是一个object类型的实例,只能用来tostring,没有引用部件类库,也不能用里面的成员方法. 本篇,我们逐渐往简单的文件 ...
- MEF入门之不求甚解,但力求简单能讲明白(三)
上一篇我们已经获得了制定类型的实例,但我们还无法对其进行有效的控制. 我们用ExportMetadata属性可以对具体的某个实例做标记,相当于命名.这么理解不知道对否. 在IPart项目中添加一个接口 ...
- 『NiFi 学习之路』入门 —— 下载、安装与简单使用
一.概述 "光说不练假把式." 官网上的介绍多少让人迷迷糊糊的,各种高大上的词语仿佛让 NiFi 离我们越来越远. 实践是最好的老师.那就让我们试用一下 NiFi 吧! 二.安装 ...
- 【转载】salesforce 零基础开发入门学习(六)简单的数据增删改查页面的构建
salesforce 零基础开发入门学习(六)简单的数据增删改查页面的构建 VisualForce封装了很多的标签用来进行页面设计,本篇主要讲述简单的页面增删改查.使用的内容和设计到前台页面使用的 ...
- Nodejs入门-基于Node.js的简单应用
服务端JavaScript 众所周知的,JavaScript是运行在浏览器的脚本语言,JavaScript通常作为客户端程序设计语言使用,以JavaScript写出的程序常在用户的浏览器上运行.直至N ...
- 机器学习入门 一、理解机器学习+简单感知机(JAVA实现)
首先先来讲讲闲话 如果让你现在去搞机器学习,你会去吗?不会的话是因为你对这方面不感兴趣,还是因为你觉得这东西太难了,自己肯定学不来?如果你觉的太难了,很好,相信看完这篇文章,你就会有胆量踏入机器学习这 ...
- 相比之前其他几个入门的, 推荐: 简单vue2 入门教程
注意:Vue.js 不支持 IE8 及其以下 IE 版本. 具体可以看下 http://www.runoob.com/vue2/vue-tutorial.html 以下是学习过程 Vue ...
随机推荐
- OpenCV 3.0函数库索引
================================== 前言:值的个数: cvCrossProduct:计算两个三维向量的向量积(叉积): cvCvtColor:将数组的通道从一个颜色空 ...
- Git学习笔记(4)——添加远程仓库,克隆远程库,以及库的推送
本文记录了远程库的连接和库的克隆和推送. 远程仓库简介 Git是分布式版本控制系统,同一个Git仓库,可以分布到不同的机器上.有一台机器有一个原始版本库,此后,别的机器可以“克隆”这个原始版本库,而且 ...
- 每天一个linux命令(55):traceroute命令
通过traceroute我们可以知道信息从你的计算机到互联网另一端的主机是走的什么路径.当然每次数据包由某一同样的出发点(source)到达某一同样的目的地(destination)走的路径可能会不 ...
- Java-异常处理练习
1.建立exception包,编写TestException.java程序,主方法中有以下代码,确定其中可能出现的异常,进行捕获处理. package Yichang; public class Te ...
- Yii 框架学习--02 进阶
应用结构 入口文件 文件位置: web/index.php <?php //开启debug,应用会保留更多日志信息,如果抛出异常,会显示详细的错误调用堆栈 defined('YII_DEBUG' ...
- lua二进制操作函数
由于 Lua 脚本语言本身不支持对数字的二进制操作(例如 与,或,非 等操作),MUSHclient 为此提供了一套专门用于二进制操作的函数,它们都定义在一个“bit”表中,使用时只要requre “ ...
- Atitit 深入了解UUID含义是通用唯一识别码 (Universally Unique Identifier),
Atitit 深入了解UUID含义是通用唯一识别码 (Universally Unique Identifier), UUID1 作用1 组成1 全球唯一标识符(GUID)2 UUID 编辑 UUID ...
- asp.net Web.config 在不同版本的IIS配置的IHttpHandler的访问路径,以及经典模式和集成模式不同的配置
如果IIS7.0使用.net4.0以上版本的框架,<system.web>中的httpHandlers节点就没有用了,而应该使用微软专为.net4.0以上版本设计的新节点<syste ...
- Mybatis中SqlMapper配置的扩展与应用(3)
隔了两周,首先回顾一下,在Mybatis中的SqlMapper配置文件中引入的几个扩展机制: 1.引入SQL配置函数,简化配置.屏蔽DB底层差异性 2.引入自定义命名空间,允许自定义语句级元素.脚本级 ...
- Open Cascade Data Exchange STL
Open Cascade Data Exchange STL eryar@163.com 摘要Abstract:介绍了三维数据交换格式STL的组成,以及Open Cascade中对STL的读写.并将O ...