组合部件通过 [System.ComponentModel.Composition.ExportAttribute] 特性声明导出。MEF 有几种不同的方式声明导出,包括在部件层面(Part Level),通过属性(Properties)和方法(Method)声明导出。
 
 
组合部件导出(Composable Part Exports)
 
 
当组合部件需要导出自身时候使用组合部件层面导出。为了组合部件导出自身,如下例代码所示,仅仅利用 [System.ComponentModel.Composition.ExportAttribute] 特性标识组合部件。
 
  1. public class SomeComposablePart { }
 
 
属性导出(Property Exports)
 
部件也可导出属性。属性导出的优势有几点原因。

 
 
  • 允许导出密封类(Sealed Types),比如:核心 CLR 类型,或者其他三方类型。
  • 允许如何创建导出中解耦。比如:导出运行时(Runtime)为你创建存在的 HttpContext。
  • 允许相同的组合部件拥有继承关系的导出,比如:DefaultSendersRegistry 组合部件导出默认的一组 Sender 作为属性。
 
 
如下例:可能有一个配置类(Configuration Class)导出一个整形(Integer)的“TImeout”契约。
 
  1. public class Configuration
  2. {
  3. [Export("Timeout")]
  4. public int Timeout
  5. {
  6. get { return int.Parse(ConfigurationManager.AppSettings["Timeout"]); }
  7. }
  8. }
  9.  
  10. [Export]
  11. public class UsesTimeout
  12. {
  13. [Import("Timeout")]
  14. public int Timeout { get; set; }
  15.  
  16. public UsesTimeout()
  17. {
  18. Compose();
  19. }
  20.  
  21. private void Compose()
  22. {
  23. //var container = new CompositionContainer();
  24. //container.ComposeParts(this, new EmailSender());
  25. AssemblyCatalog catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
  26. var container = new CompositionContainer(catalog);
  27. container.ComposeParts(this);
  28. }
  29. }
 
 
方法导出(Method Exports)
 
方法导出是指部件导出其中一个方法。方法指定为导出契约,作为委托(Delegates)被导出。方法导出包括下面的许多优势。

 
 
 
  • 允许更细力度的控制导出什么。比如:规则引擎(Rules Engine)可能导入一组可插拔(Pluggable)的方法导出。
  • 规避了调用者对类型的认知情况。
  • 可以通过 Light Code Gen 生成,which you cannot do with the other exports。
 
注意:由于框架限制,方法导出不能超出4个参数。
下面的例子中,MessageSender 类的 Send 方法作为 Action<string> 委托导出。Processor 类导入同样的委托。
 
  1. public class MessageSender
  2. {
  3. [Export(typeof(Action<string>))]
  4. public void Send(string message)
  5. {
  6. Console.WriteLine(message);
  7. }
  8. }
  9.  
  10. [Export]
  11. public class Processor
  12. {
  13. [Import(typeof(Action<string>))]
  14. public Action<string> MessageSender { get; set; }
  15.  
  16. public void Send()
  17. {
  18. MessageSender("Processed");
  19. }
  20.  
  21. public Processor()
  22. {
  23. Compose();
  24. }
  25.  
  26. private void Compose()
  27. {
  28. //var container = new CompositionContainer();
  29. //container.ComposeParts(this, new EmailSender());
  30. AssemblyCatalog catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
  31. var container = new CompositionContainer(catalog);
  32. container.ComposeParts(this);
  33. }
  34. }
 
 
你也可以使用简单字符约束(Simple String Contract)导出导入方法。例如:下面的“Sender”约束的使用。
 
  1. public class MessageSender
  2. {
  3. [Export("MessageSender")]
  4. public void Send(string message)
  5. {
  6. Console.WriteLine(message);
  7. }
  8. }
  9.  
  10. [Export]
  11. public class Processor
  12. {
  13. [Import("MessageSender")]
  14. public Action<string> MessageSender { get; set; }
  15.  
  16. public void Send()
  17. {
  18. MessageSender("Processed");
  19. }
  20.  
  21. public Processor()
  22. {
  23. Compose();
  24. }
  25.  
  26. private void Compose()
  27. {
  28. //var container = new CompositionContainer();
  29. //container.ComposeParts(this, new EmailSender());
  30. AssemblyCatalog catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
  31. var container = new CompositionContainer(catalog);
  32. container.ComposeParts(this);
  33. }
  34. }
 
注意:当做方法导出时,必须提供类型或者字符约束名,而不能留空。
 
继承导出
 
MEF 支持基类/接口定义导出,由实现者自动继承的能力。利用 MEF 和遗留框架集成,但是又不想修改现有的客户代码,这是理想的。System.ComponentModel.Composition.InheritedExportAttribute 特性提供这种能力。例如:ILogger 标识了继承导出的特性。Logger 实现了 ILogger,因此自动实现了 ILogger 的导出。
 
  1. [InheritedExport]
  2. public interface ILogger
  3. {
  4. void Log(string message);
  5. }
  6.  
  7. public class Logger : ILogger
  8. {
  9. public void Log(string message) { }
  10. }
 
 
发现非公开(Non-Public)组合部件
 
MEF 支持发现公开和非公开的部件。你无须为了这种用法做任何事情。请注意:在 medium/partial trust 环境(包括 Sliverlight)非公开组合将不被支持。

 

MEF 编程指南(三):声明导出的更多相关文章

  1. MEF 编程指南(六):导出和元数据

    声明导出解释了部件导出服务的基础知识和价值观(Values).有时候出于种种原因,导出关联信息是非常必要的.通常,用于解释关于功能公共契约的具体实现.允许导入满足约束要求的导出,或者导入所有可用的实现 ...

  2. MEF 编程指南(二):定义可组合部件和契约

    可组合部件(Composable Parts)   在 MEF 内部可组合部件是一个可组合单元.可组合部件导出其他可组合部件需要的服务,并且从其他可组合部件导入服务.在 MEF 编程模型中,可组合部件 ...

  3. MEF 编程指南(四):声明导入

    组合部件通过 [System.ComponentModel.Composition.ImportAttribute] 特性声明导入.类似于导出,也有几种不同的方法声明导入,即通过:字段(Fields) ...

  4. MEF 编程指南(五):延迟导出

    在组合部件的时候,导入将会触发部件(部件集合)的实例化,为原始的请求部件公开必要的导出需求.对于有些应用程序,推迟实例化 - 并且防止递归组合图(Recursive Composition Down ...

  5. MEF 编程指南(七):使用目录

    目录(Catalogs)   MEF 特性编程模型的核心价值,拥有通过目录动态地发现部件的能力.目录允许应用程序轻松地使用那些通过 Export Attribute 注册自身的导出.下面列出 MEF ...

  6. MEF 编程指南(十二):批量组合

    MEF 容器实例并非不可变的.如果目录支持改变(像监控目录变动)或者在运行时添加/移除部件都可能发生改变.以前,你不得不做出改动并且调用 CompositionContainer 上的 Compose ...

  7. MEF 编程指南(十一):查询 CompositionContainer

    CompositionContainer 公开了一部分获取导出.导出对象以及两者集合的重载.   在这些方法重载中,你应该遵循下面的共享行为准则 - 除非特别说明.   当请求单一实例的时候,如果没发 ...

  8. MEF 编程指南(九):部件生命周期

    理解 MEF 容器部件生命周期和实现是非常重要的事情.考虑到 MEF 关注可扩展应用程序.这变得尤为重要.生命期可以解释为期望部件的共享性(transitively, its exports)   共 ...

  9. MEF 编程指南(一):在应用中托管 MEF

    在应用程序中托管(Hosing) MEF 涉及到创建组合容器(CompositionContainer) 实例,添加可组合部件(Composable Parts),包括应用程序宿主(Host)本身并进 ...

随机推荐

  1. vc/mfc获取rgb图像数据后动态显示及保存图片的方法

    vc/mfc获取rgb图像数据后动态显示及保存图片的方法 该情况可用于视频通信中获取的位图数据回放显示或显示摄像头捕获的本地图像 第一种方法 #include<vfw.h> 加载 vfw3 ...

  2. 在delphi中, reintroduce作用

    在delphi中, reintroduce作用 当在子类中重载或者重新声明父类的虚方法时,使用     reintroduce   关键字告知编译器,可以消除警告信息.如:          TPar ...

  3. Android02--debug.keystore的注册信息

    1 -- 签名文件的密钥 默认签名文件的密码是:android 该文件的存放点是: 2 -- 签名文件的签名信息 keytool -list -v -keystore C:\Users\motadou ...

  4. 底部菜单栏(二) TabHost & RadioGroup 实现

    需求:使用TabHost & RadioGroup实现底部菜单栏: 效果图: 实现分析: 1.目录结构: 代码实现: 1. activity_main.xml <?xml version ...

  5. 如何在linux中搭建JEECMS系统

    本人正在进行jeecms二次开发,但因win7系统中的Tomcat无法使用,就想起在linux下安装,但去jeecms的官方网站,没有给出在linux下安装的方法,确实苦恼,经过一天的研究,终于大功告 ...

  6. [转]python类方法

    Python定义类-方法 公有方法.私有方法.类方法.静态方法

  7. POJ 1573 Robot Motion

    Robot Motion Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 12978   Accepted: 6290 Des ...

  8. Oracle 存储过程动态建表

    动态sql,顾名思义就是动态执行的sql,也就是说在没执行之前是动态的拼接的. 任务 传入参数:新建的表名hd+当前的年和月,例如hd_201105表结构是:字段1:id ,类型是number,可以自 ...

  9. <转>亲手缔造DNS体系,创建DNS私有根:DNS系列之六

    打造DNS私有根 我们现在已经从前面的博文中了解到了很多DNS的相关知识,今天我们用一个综合性的实验把前面的内容都串起来复习一下,这个有趣的实验就是DNS的私有根.私有根顾名思义是由个人或企业自行创建 ...

  10. web服务器分析与设计(一)

    自己写一个简单的服务器. 面向对象分析与设计第一步:获取需求(基于用例) 功能:1,支持html静态网页,2,支持常用HTTP请求,且容易扩展支持不现请求 3,可以发布站点 补充:至于对动态网页等高级 ...