一、演示概述

此演示初步介绍了MEF的基本使用,包括对MEF中的Export、Import和Catalog做了初步的介绍,并通过一个具体的Demo来展示MEF是如何实现高内聚、低耦合和高扩展性的软件架构。
演示中,针对于IBookService接口,有3个不同版本的实现,分别是ComputerBookServiceImp、HistoryBookServiceImp和MathBookServiceImp,然后通过MEF的导入导出及组装机制,分别在这3个版本的实现间替换,而这种替换并未通过配置文件之类的辅助方式,使用起来,确实有它的方便之处。
相关下载(屏幕录像)http://yunpan.cn/cZnDLgASnvTj8 访问密码 39e7
在线播放http://v.youku.com/v_show/id_XOTIwNjkyNjY0.html
温馨提示:如果屏幕录像和代码不能正常下载,可站内留言,或发邮件到524130780@QQ.COM

欢迎有兴趣研究.NET相关技术的网友加QQ群:18507443

二、关键代码

接口定义:

  1. namespace Interface
  2. {
  3. public interface IBookService
  4. {
  5. void GetBookName();
  6. }
  7. }

针对于接口的3个实现,如下代码所示:

  1. using System;
  2. using System.ComponentModel.Composition;
  3. using Interface;
  4. namespace ComputerBookServiceImp
  5. {
  6. [Export(typeof(IBookService))]
  7. public class ComputerBookService : IBookService
  8. {
  9. public void GetBookName()
  10. {
  11. Console.WriteLine("Computer Book");
  12. }
  13. }
  14. }

上面代码除了对接口的实现以外,有两点需要说明的:
1、项目中引用了System.ComponentModel.Composition程序集,使用MEF必须使用该程序集。
2、使用了Export特性标记了ComputerBookService类,并且声明其类型为IBookServivce,通过此特性说明该类是MEF的一个导出部件。

其他两个版本的实现和上面雷同,代码如下:

HistoryBookServiceImp

  1. using System;
  2. using System.ComponentModel.Composition;
  3. using Interface;
  4. namespace HistoryBookServiceImp
  5. {
  6. [Export(typeof(IBookService))]
  7. public class HistoryBookService : IBookService
  8. {
  9. public void GetBookName()
  10. {
  11. Console.WriteLine("History Book");
  12. }
  13. }
  14. }

MathBookServiceImp

  1. using System;
  2. using System.ComponentModel.Composition;
  3. using Interface;
  4. namespace MathBookServiceImp
  5. {
  6. [Export(typeof(IBookService))]
  7. public class MathBookService : IBookService
  8. {
  9. public void GetBookName()
  10. {
  11. Console.WriteLine("Math Book");
  12. }
  13. }
  14. }

然后在修改控制台应用程序Proggram类的代码如下所示:

  1. using System.ComponentModel.Composition;
  2. using System.ComponentModel.Composition.Hosting;
  3. using Interface;
  4. namespace HostApp
  5. {
  6. class Program
  7. {
  8. static void Main(string[] args)
  9. {
  10. Program program = new Program();
  11. program.Compose();
  12. program.BookService.GetBookName();
  13. }
  14. [Import]
  15. public IBookService BookService { get; set; }
  16. /// <summary>
  17. /// 通过容器对象将宿主和部件组装到一起。
  18. /// </summary>
  19. public void Compose()
  20. {
  21. DirectoryCatalog directoryCatalog = new DirectoryCatalog("imps");
  22. var container = new CompositionContainer(directoryCatalog);
  23. container.ComposeParts(this);
  24. }
  25. }
  26. }

上面的代码有3点需要说明:
1、通过Import特性标记BookService为一个导入属性,这样MEF的容器在进行宿主和部件组装的时候,将会查找与之匹配的导出部件,然后进行组装。上述代码所查找的是类型与BooService类型相同的导出部件。
2、通过使用DirectoryCatalog类指明要查找的导出部件位于应用程序根目录下的imps子文件夹中。
3、通过CompositionContainer的扩展方法ComposeParts()组装宿主程序和导出部件。在该方法执行前,BookService属性值为null,运行后,如果找到匹配的导出部件,则创建了该导出部件的一个实例。

三、相关资源
1、MSDN官方资料:http://msdn.microsoft.com/zh-cn/library/dd460648(v=vs.110).aspx
2、参考了微软MVP Bēniaǒ的文章《MEF程序设计指南一:在应用程序中宿主MEF》,访问地址:http://www.cnblogs.com/beniao/archive/2010/07/03/1770276.html

[MEF]第01篇 MEF使用入门的更多相关文章

  1. [MEF]第03篇 MEF延迟加载导出部件及元数据

    一.演示概述此演示介绍了MEF的延迟加载及元数据相关的内容.在实际的设计开发中,存在着某些对象是不需要在系统运行或者附属对象初始化的时候进行实例化的,只需要在使用到它的时候才会进行实例化,这种方式就可 ...

  2. [MEF]第04篇 MEF的多部件导入(ImportMany)和目录服务

    一.演示概述此演示介绍了MEF如何使用ImportMany特性同时导入多个与相同约束相匹配的导出部件,并且介绍了目录服务(Catalog),该服务告知MEF框架可以在什么地方去搜寻与指定约束匹配的导出 ...

  3. [MEF]第05篇 MEF的目录(Catalog)筛选

    一.演示概述本示例演示如何使用MEF提供的目录(Catalog)的扩展机制实现可过滤导出部件的自定义目录类.主要是通过继承ComposablePartCatalog基类,并实现接口INotifyCom ...

  4. [MEF]第02篇 MEF的导入导出契约

    一.演示概述此演示介绍了如何为Export指定导出的协议名和类型,以及如何为Import指定导入的协议名和类型,只有确保导出和导入的协议名和类型相匹配了,才能注入成功,否则注入就会失败.相关下载(屏幕 ...

  5. 033 01 Android 零基础入门 01 Java基础语法 03 Java运算符 13 运算符和表达式知识点总结

    033 01 Android 零基础入门 01 Java基础语法 03 Java运算符 13 运算符和表达式知识点总结 本文知识点:运算符和表达式知识点总结 前面学习的几篇文都是运算符和表达式相关的知 ...

  6. 020 01 Android 零基础入门 01 Java基础语法 02 Java常量与变量 14 变量与常量 知识总结

    020 01 Android 零基础入门 01 Java基础语法 02 Java常量与变量 14 变量与常量 知识总结 本文知识点:变量与常量 知识总结 Java中的标识符 Java中的关键字 目前常 ...

  7. 016 01 Android 零基础入门 01 Java基础语法 02 Java常量与变量 10 布尔类型和字符串的字面值

    016 01 Android 零基础入门 01 Java基础语法 02 Java常量与变量 10 布尔类型和字符串的字面值 本文知识点:字面值 关于字面值的概念,需要注意:很多地方,我们可能就把字面值 ...

  8. 推荐csdn里的几篇activiti基础入门及提高的博客

    昨天有个网友加qq询问我有没有非maven搭建的activiti项目的demo,因为我博客中写了一个用maven,我当时没有,于是晚上回家尝试了一下,结果比较容易就实现了. 之后和那个网友聊了一下,他 ...

  9. RabbitMQ学习总结 第二篇:快速入门HelloWorld

    目录 RabbitMQ学习总结 第一篇:理论篇 RabbitMQ学习总结 第二篇:快速入门HelloWorld RabbitMQ学习总结 第三篇:工作队列Work Queue RabbitMQ学习总结 ...

随机推荐

  1. [Vue]使用axios实现ajax请求

    1.定义myAjax export const myAjax=function createHttpClient(ajaxConfig) {   let httpClient = null;   if ...

  2. PHP libevent函数基本介绍

    3.2   主要函数介绍 按照使用libevnet库顺序,看一下相关函数做什么操作. 3.2.1  event_init 调用event_base_new,初始化struct event_base对象 ...

  3. poj-3461-kmp模板题。。。

    Oulipo Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 46290   Accepted: 18452 Descript ...

  4. HDU 4828 逆元+catalan数

    Grids Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Subm ...

  5. C#/JAVA 程序员转GO/GOLANG程序员笔记大全(DAY 00)

    一.安装说明 https://studygolang.com/dl 二.环境变量 // 下载 *.msi 安装文件,部分环境变量默认配置好了. 其他配置如下描述 三.目录及项目层级关系 在系统环境变量 ...

  6. POJ 1568 极大极小搜索 + alpha-beta剪枝

    极小极大搜索 的个人理解(alpha-beta剪枝) 主要算法依据就是根据极大极小搜索实现的. 苦逼的是,查了两个晚上的错,原来最终是判断函数写错了..瞬间吐血! ps. 据说加一句 if sum & ...

  7. Ansible 小手册系列 八(Yaml 语法格式)

    YAML 语言(发音 /ˈjæməl/ )的设计目标,就是方便人类读写.它实质上是一种通用的数据串行化格式. 它的基本语法规则如下. • 大小写敏感 • 使用缩进表示层级关系 • 缩进时不允许使用Ta ...

  8. redhat9安装gcc(转)

    原文链接:http://blog.chinaunix.net/uid-20260767-id-118036.html 第一种方法: 相信现在还有不少人在用经典的RedHat9,毕竟他是完全免费的红帽L ...

  9. GPU编程自学2 —— CUDA环境配置

    深度学习的兴起,使得多线程以及GPU编程逐渐成为算法工程师无法规避的问题.这里主要记录自己的GPU自学历程. 目录 <GPU编程自学1 -- 引言> <GPU编程自学2 -- CUD ...

  10. Android深入理解JNI(二)类型转换、方法签名和JNIEnv

    相关文章 Android深入理解JNI系列 前言 上一篇文章介绍了JNI的基本原理和注册,这一篇接着带领大家来学习JNI的数据类型转换.方法签名和JNIEnv. 1.数据类型的转换 首先给出上一篇文章 ...