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 ... 
随机推荐
- java系统性能分析
			netstat -ano | findstr 31900 注意最后是pid 堆栈的作用: 线程死锁分析 辅助CPU过高分析 线程资源不足分析 性能瓶颈分析 关键线程异常退出 Windows:在运行ja ... 
- display的理解
			display可把框内显示的内容改变(自我理解) none 此元素不会被显示. block 此元素将显示为块级元素,此元素前后会带有换行符. inline 默认.此元素会被显示为内联元素,元素前后没有 ... 
- python多线程网络编程
			背景 使用过flask框架后,我对request这个全局实例非常感兴趣.它在客户端发起请求后会保存着所有的客户端数据,例如用户上传的表单或者文件等.那么在很多客户端发起请求时,服务器是怎么去区分不同的 ... 
- WPF入门教程系列四——Dispatcher介绍
			一.Dispatcher介绍 微软在WPF引入了Dispatcher,那么这个Dispatcher的主要作用是什么呢? 不管是WinForm应用程序还是WPF应用程序,实际上都是一个进程,一个进程可以 ... 
- linux执行sh脚本文件命令
			linux执行sh脚本文件命令 很多时候需要多个命令来完成一项工作,而这个工作又常常是重复的,这个时候我们自然会想到将这些命令写成sh脚本,下次执行下这个脚本一切就都搞定了,下面就是发布代码的一个脚本 ... 
- KnockoutJS 3.X API 第二章 数据监控(1)视图模型与监控
			数据监控 KO的三个内置核心功能: 监控(Observable)和依赖性跟踪(dependency tracking) 声明绑定(Declarative bindings) 模板(Templating ... 
- Oracle 11g系列:SQL Plus与PL/SQL
			SQL Plus是Oracle提供的一种用户接口,是数据库与用户之间进行交互的工具. PL/SQL是Oracle的过程化编程语言. 1.登录SQL Plus 利用Windows的[开始]|[运行]命令 ... 
- 探讨js字符串数组拼接的性能问题
			这篇文章主要介绍了有关js对字符串数组进行拼接的性能问题,字符串连接一直是js中性能最低的操作之一,应该如何解决呢?请参看本文的介绍 我们知道,在js中,字符串连接是性能最低的操作之一. 例如: 复制 ... 
- .NET面试题解析(04)-类型、方法与继承
			系列文章目录地址: .NET面试题解析(00)-开篇来谈谈面试 & 系列文章索引 做技术是清苦的.一个人,一台机器,相对无言,代码纷飞,bug无情.须梦里挑灯,冥思苦想,肝血暗耗,板凳坐穿 ... 
- gridview里日期显示格式
			Text='<%#Bind("EndDate","{0:yyyy-MM-dd}") %>' 
