转自:http://www.cnblogs.com/yunfeifei/p/3922891.html

上一篇学习完了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);}}
}

这样就可以正常运行了~~

c# MEF框架(二 MEF的导出(Export)和导入(Import))相关推荐

  1. UG\NX二次开发 导出x_t、导入x_t例子UF_PS_export_data、UF_PS_import_data

    文章作者:里海 来源网站:https://blog.csdn.net/WangPaiFeiXingYuan 简介: 获取blockUI 体收集器选择的体,导出x_t:导入x_t后不显示,还要用函数UF ...

  2. 【C#进阶系列】【MEF框架(一)】

    C#进阶系列 第一章 [C#进阶系列][MEF框架(一)] 文章目录 C#进阶系列 前言 一.MEF介绍 二.为什么要用MEF 三.MEF的概念 四.使用示例 五.MEF框架的好处 六.源码链接 总结 ...

  3. MEF初体验之六:导出和元素据

    在导出声明这一节中解释了部件导出服务和值的基础知识.在某些情况下,出于多种原因,关联与导出相关的信息是有必要的.通常,它被用来解释一个指定的普通契约实现的能力.这对于允许导入约束满足它的导出,或者导入 ...

  4. Laravel框架使用maatwebsite/excel导出自动换行

    Laravel框架使用maatwebsite/excel导出自动换行 maatwebsite/excel 版本:2.1 $sheet->getStyle("A6:F6")-& ...

  5. 第4.2章:StarRocks数据导出--Export

    Export是StarRocks提供的将数据导出至HDFS.OSS.COS或S3等对象存储上的导出方式(当前仅支持导出为CSV文件),使用Export需要在集群中提前部署Broker组件. Expor ...

  6. SVN中检出(check out) 和导出(export) 的区别

    SVN中检出(check out) 和导出(export) 的区别 观点一: SVN是常用的一种常见的版本控制软件.SVN中检出(check out) 和 导出(export) 的区别主要有如下几条: ...

  7. check在java意思吗_SVN中检出(check out) 跟导出(export) 的区别

    SVN中检出(check out) 和导出(export) 的区别?观点一:SVN是常用的一种常见的版本控制软件.SVN中检出(check SVN中检出(check out) 和导出(export) ...

  8. opencart导入导出export/import功能插件

    2019独角兽企业重金招聘Python工程师标准>>> 本版本仅适用于 opencart 1.5.5及 opencart 1.5.5.1,请下载者注意. 功能:网站管理员可以进行批量 ...

  9. SVN中检出(check out) 和 导出(export) 的区别

    SVN是常用的一种常见的版本控制软件.SVN中检出(check out) 和 导出(export) 的区别主要有如下几条: check out跟check in对应,export跟import对应. ...

最新文章

  1. 超酷flash光芒光线特效
  2. ReviewForJob——算法设计技巧(贪婪算法+分治算法+动态规划)
  3. 《深入实践Spring Boot》一3.3 使用Thymeleaf模板
  4. 【luogu3834】【POJ2104】【模板】可持久化线段树 1 [主席树]
  5. npm的安装和更新---npm工作笔记002
  6. Python编写区块链
  7. 【mysql】关于IO/内存方面的一些优化
  8. MoSonic:对SubSonic的分布式存储、缓存改进方案尝试(1)
  9. 小程序获取openid时报40125
  10. 计算机应用 一级学科,一级学科、二级学科,考研专业哪个包含了计算机考研方向...
  11. 基于wine葡萄酒数据集的分类方法研究
  12. STM32F103C8T6 点亮LED灯
  13. DOS下Debug工具使用
  14. 学习笔记(3):海量数据的交互式分析工具-Dremel
  15. git 代码记录单条合并的方法
  16. 查看linux版本是多少位
  17. 线程中的setDaemon方法
  18. 词表大小越界错误 indexSelectLargeIndex
  19. 基于矩阵分解的协同过滤推荐
  20. windows服务器svn迁移到linux服务器svn3

热门文章

  1. PKU 学生的反馈 2009-1
  2. JAVA进阶教学之(一维数组)
  3. IOC操作Bean管理XML方式(外部属性文件)
  4. JAVA入门级教学之(异常机制的原理到底是什么)
  5. java 文件通道_Java NIO(四)文件通道
  6. 怎么用记事本写java_如何用记事本写下第一个Java程序-Fun言
  7. caged系统pdf_建筑行业单词中英文对照教材.pdf
  8. 热门专业学习之关于java的一些知识
  9. 计算机网络与通信思维导图,用思维导图描述5G场景
  10. 查看linux系统的sp,查看linux系统版本命令