C#可扩展编程之MEF学习笔记(二):MEF的导出(Export)和导入(Import)
上一篇学习完了MEF的基础知识,编写了一个简单的DEMO,接下来接着上篇的内容继续学习,如果没有看过上一篇的内容,
请阅读:http://www.cnblogs.com/yunfeifei/p/3922668.html。
下面我们来主要讲解一下MEF中的导入和导出,还是上一篇的代码(这篇中,我还会贴出完整的代码),修改Program的代码如下:
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Reflection;
- using System.ComponentModel.Composition;
- using System.ComponentModel.Composition.Hosting;
- namespace MEFDemo
- {
- class Program
- {
- [Import("MusicBook")]
- public IBookService Service { get; set; }
- static void Main(string[] args)
- {
- Program pro = new Program();
- pro.Compose();
- if (pro.Service != null)
- {
- Console.WriteLine(pro.Service.GetBookName());
- }
- Console.Read();
- }
- private void Compose()
- {
- var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
- CompositionContainer container = new CompositionContainer(catalog);
- container.ComposeParts(this);
- }
- }
- }
修改MusicBook的代码如下:
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.ComponentModel.Composition;
- namespace MEFDemo
- {
- [Export("MusicBook",typeof(IBookService))]
- public class MusicBook : IBookService
- {
- public string BookName { get; set; }
- public string GetBookName()
- {
- return "MusicBook";
- }
- }
- }
注意,标红的是改动过的地方,其他地方的代码没有变,上一次我们使用的是Export的方法是[Export(typeof(IBookService))],这次前面多了一个参数,没错,这个就是一个契约名,名字可以随便起,而且可以重复,但是如果名字乱起,和其他DLL中的重复,到时候会导致程序出现很多Bug,最好按照一定的规范去起名字。
这里有了契约名以后,导入(Import)时就要指定的契约名,否则将无法找到MusicBook,Export还有一个方法是[Export("Name")],这个方法只指定了契约名,没有指定导出类型,那么默认的导出类型是object类型,在导入时导出到的对象就要为object类型,否则将匹配不到那个组件。
到现在,我们只写了一个接口和一个实现类,导出的也是一个类,下面我们多添加几个类来看看会怎么样,为了方便大家测试,我把实现接口的类写在一个文件里面,新加几个类后,的MusicBook类文件代码如下:
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.ComponentModel.Composition;
- namespace MEFDemo
- {
- [Export("MusicBook",typeof(IBookService))]
- public class MusicBook : IBookService
- {
- public string BookName { get; set; }
- public string GetBookName()
- {
- return "MusicBook";
- }
- }
- [Export("MusicBook", typeof(IBookService))]
- public class MathBook : IBookService
- {
- public string BookName { get; set; }
- public string GetBookName()
- {
- return "MathBook";
- }
- }
- [Export("MusicBook", typeof(IBookService))]
- public class HistoryBook : IBookService
- {
- public string BookName { get; set; }
- public string GetBookName()
- {
- return "HistoryBook";
- }
- }
- }
这里添加两个类,HistoryBook和MathBook,都继承自IBookService接口,注意他们的契约名都相同,都为MusicBook,后面再详细的说这个问题,修改后的program的代码如下:
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Reflection;
- using System.ComponentModel.Composition;
- using System.ComponentModel.Composition.Hosting;
- namespace MEFDemo
- {
- class Program
- {
- [ImportMany("MusicBook")]
- public IEnumerable<IBookService> Services { get; set; }
- static void Main(string[] args)
- {
- Program pro = new Program();
- pro.Compose();
- if (pro.Services != null)
- {
- foreach (var s in pro.Services)
- {
- Console.WriteLine(s.GetBookName());
- }
- }
- Console.Read();
- }
- private void Compose()
- {
- var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
- CompositionContainer container = new CompositionContainer(catalog);
- container.ComposeParts(this);
- }
- }
- }
这里需要注意的是标红的两行代码,[ImportMany("MusicBook")]还有下面的声明变成了IEnumerable<>,因为要导出多个实例,所以要用到集合,下面采用foreach遍历输出,运行的结果如下图:
一共三个,都输出了,对吧!是不是很好用啊,哈哈~~
当然,如果想全部输出,可以向第一篇文章中那样,导入和导出时都不写契约名,就会全部导出。那么写契约名有什么好处呢?
下面我们用代码说明问题,修改实现类的契约名如下:
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.ComponentModel.Composition;
- namespace MEFDemo
- {
- [Export("MusicBook",typeof(IBookService))]
- public class MusicBook : IBookService
- {
- public string BookName { get; set; }
- public string GetBookName()
- {
- return "MusicBook";
- }
- }
- [Export("MathBook", typeof(IBookService))]
- public class MathBook : IBookService
- {
- public string BookName { get; set; }
- public string GetBookName()
- {
- return "MathBook";
- }
- }
- [Export("HistoryBook", typeof(IBookService))]
- public class HistoryBook : IBookService
- {
- public string BookName { get; set; }
- public string GetBookName()
- {
- return "HistoryBook";
- }
- }
- }
现在三个类的契约名都不相同了,其他的代码不动,再次运行程序看看,是不是现在只输出MusicBook了,同理,修改[Import("Name")]中的契约名称,就会导入指定含有名称的类,契约名可以重复,这一以来,我们就可以用契约名给类进行分类,导入时可以根据契约名来导入。
注意:IEnumerable<T>中的类型必须和类的导出类型匹配,如类上面标注的是[Exprot(typeof(object))],那么就必须声明为IEnumerable<object>才能匹配到导出的类。
例如:我们在类上面标注[Export("Book")],我们仅仅指定了契约名,而没有指定类型,那么默认为object,此时还用IEnumerable<IBookService>就匹配不到。
那么,这种情况就要在输出是进行强制类型转换,代码如下:
- [Export("MusicBook")]
- public class MusicBook : IBookService
- {
- public string BookName { get; set; }
- public string GetBookName()
- {
- return "MusicBook";
- }
- }
program中的代码改变如下:
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Reflection;
- using System.ComponentModel.Composition;
- using System.ComponentModel.Composition.Hosting;
- namespace MEFDemo
- {
- class Program
- {
- [ImportMany("MusicBook")]
- public IEnumerable<object> Services { get; set; }
- static void Main(string[] args)
- {
- Program pro = new Program();
- pro.Compose();
- if (pro.Services != null)
- {
- foreach (var s in pro.Services)
- {
- var ss = (IBookService)s;
- Console.WriteLine(ss.GetBookName());
- }
- }
- Console.Read();
- }
- private void Compose()
- {
- var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
- CompositionContainer container = new CompositionContainer(catalog);
- container.ComposeParts(this);
- }
- }
- }
这样就可以正常运行了~~
MEF系列文章:
C#可扩展编程之MEF学习笔记(一):MEF简介及简单的Demo
C#可扩展编程之MEF学习笔记(二):MEF的导出(Export)和导入(Import)
C#可扩展编程之MEF学习笔记(二):MEF的导出(Export)和导入(Import)的更多相关文章
- C#可扩展编程之MEF学习笔记(五):MEF高级进阶
好久没有写博客了,今天抽空继续写MEF系列的文章.有园友提出这种系列的文章要做个目录,看起来方便,所以就抽空做了一个,放到每篇文章的最后. 前面四篇讲了MEF的基础知识,学完了前四篇,MEF中比较常用 ...
- C#可扩展编程之MEF学习笔记(四):见证奇迹的时刻
前面三篇讲了MEF的基础和基本到导入导出方法,下面就是见证MEF真正魅力所在的时刻.如果没有看过前面的文章,请到我的博客首页查看. 前面我们都是在一个项目中写了一个类来测试的,但实际开发中,我们往往要 ...
- C#可扩展编程之MEF学习笔记(三):导出类的方法和属性
前面说完了导入和导出的几种方法,如果大家细心的话会注意到前面我们导出的都是类,那么方法和属性能不能导出呢???答案是肯定的,下面就来说下MEF是如何导出方法和属性的. 还是前面的代码,第二篇中已经提供 ...
- C#可扩展编程之MEF学习笔记(一):MEF简介及简单的Demo
在文章开始之前,首先简单介绍一下什么是MEF,MEF,全称Managed Extensibility Framework(托管可扩展框架).单从名字我们不难发现:MEF是专门致力于解决扩展性问题的框架 ...
- C#可扩展编程之MEF学习
MEF系列文章: C#可扩展编程之MEF学习笔记(一):MEF简介及简单的Demo C#可扩展编程之MEF学习笔记(二):MEF的导出(Export)和导入(Import) C#可扩展编程之MEF学习 ...
- C#可扩展编程之MEF
C#可扩展编程之MEF学习笔记(四):见证奇迹的时刻 前面三篇讲了MEF的基础和基本到导入导出方法,下面就是见证MEF真正魅力所在的时刻.如果没有看过前面的文章,请到我的博客首页查看. 前面我们都是在 ...
- AJax 学习笔记二(onreadystatechange的作用)
AJax 学习笔记二(onreadystatechange的作用) 当发送一个请求后,客户端无法确定什么时候会完成这个请求,所以需要用事件机制来捕获请求的状态XMLHttpRequest对象提供了on ...
- [Firefly引擎][学习笔记二][已完结]卡牌游戏开发模型的设计
源地址:http://bbs.9miao.com/thread-44603-1-1.html 在此补充一下Socket的验证机制:socket登陆验证.会采用session会话超时的机制做心跳接口验证 ...
- JMX学习笔记(二)-Notification
Notification通知,也可理解为消息,有通知,必然有发送通知的广播,JMX这里采用了一种订阅的方式,类似于观察者模式,注册一个观察者到广播里,当有通知时,广播通过调用观察者,逐一通知. 这里写 ...
随机推荐
- tkinter 在 x window 下的字体设置格式
X Font Descriptors # X Font Descriptors are strings having the following format (the asterisks repre ...
- 实战录 | 一起唠唠那些常见的DDoS攻击
<实战录>导语 云端卫士<实战录>栏目定期会向粉丝朋友们分享一些在开发运维中的经验和技巧,希望对于关注我们的朋友有所裨益.本期分享人为云端卫士系统架构师高鹏,将带来常见的DDo ...
- php生成器的使用
按照php的文档说明 一个生成器函数看起来像一个普通的函数,不同的是普通函数返回一个值,而一个生成器可以yield生成许多它所需要的值. 当一个生成器被调用的时候,它返回一个可以被遍历的对象.当你遍历 ...
- vue2 上传图片
<template> <div class="vue-upload-img-multiple"> <div v-if="images.len ...
- codingNet项目的创建
首先,在codingNet上面创建一个项目(一般情况下) 然后,在本地打开项目并添加到储存库 其次,提交代码到已经创建好的项目中(注意赋值远程存储库的路径)
- gitlab安装过程总结
gitlab总算搭建好了,今天下午完成了第一个工程的导入. 梳理下搭建的过程: 1.下载bitnami的一键安装包,并安装 注意设置权限为777,以免出现某文件写入错误的问题 2.配置邮件服务 分别修 ...
- css大小单位px em rem的转换和详解
css大小单位px em rem的转换和详解 PX特点1. IE无法调整那些使用px作为单位的字体大小:2. 国外的大部分网站能够调整的原因在于其使用了em或rem作为字体单位:3. Firefox能 ...
- Fiddler 工作原理
Fiddler工作原理: 就在在客户端与服务器端创建一个代理服务器: 在开启Fiddler后,Fiddler会自动窜改浏览器的代理,例如我们打开Fiddler,打开IE浏览器--设置--Interne ...
- IQD文件模板以及cs7g.ini信息
COGNOS QUERY STRUCTURE,1,1 DATABASE, cognos TITLE,test BEGIN SQL { select time, city_id, city_name, ...
- centOS升级python3.5
CentOS自带的版本是2.7.5 目前在看廖老师的教学,他给的新版本是3以上了,果断升级到最新的Python版本 (windows下面多线程里面有点问题没解决,所以才换到linux下继续学习) 一 ...