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

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

 
 
 
  • 允许更细力度的控制导出什么。比如:规则引擎(Rules Engine)可能导入一组可插拔(Pluggable)的方法导出。
  • 规避了调用者对类型的认知情况。
  • 可以通过 Light Code Gen 生成,which you cannot do with the other exports。
 
注意:由于框架限制,方法导出不能超出4个参数。
下面的例子中,MessageSender 类的 Send 方法作为 Action<string> 委托导出。Processor 类导入同样的委托。
 
    public class MessageSender
{
[Export(typeof(Action<string>))]
public void Send(string message)
{
Console.WriteLine(message);
}
} [Export]
public class Processor
{
[Import(typeof(Action<string>))]
public Action<string> MessageSender { get; set; } public void Send()
{
MessageSender("Processed");
} public Processor()
{
Compose();
} private void Compose()
{
//var container = new CompositionContainer();
//container.ComposeParts(this, new EmailSender());
AssemblyCatalog catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
var container = new CompositionContainer(catalog);
container.ComposeParts(this);
}
}
 
 
你也可以使用简单字符约束(Simple String Contract)导出导入方法。例如:下面的“Sender”约束的使用。
 
    public class MessageSender
{
[Export("MessageSender")]
public void Send(string message)
{
Console.WriteLine(message);
}
} [Export]
public class Processor
{
[Import("MessageSender")]
public Action<string> MessageSender { get; set; } public void Send()
{
MessageSender("Processed");
} public Processor()
{
Compose();
} private void Compose()
{
//var container = new CompositionContainer();
//container.ComposeParts(this, new EmailSender());
AssemblyCatalog catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
var container = new CompositionContainer(catalog);
container.ComposeParts(this);
}
}
 
注意:当做方法导出时,必须提供类型或者字符约束名,而不能留空。
 
继承导出
 
MEF 支持基类/接口定义导出,由实现者自动继承的能力。利用 MEF 和遗留框架集成,但是又不想修改现有的客户代码,这是理想的。System.ComponentModel.Composition.InheritedExportAttribute 特性提供这种能力。例如:ILogger 标识了继承导出的特性。Logger 实现了 ILogger,因此自动实现了 ILogger 的导出。
 
    [InheritedExport]
public interface ILogger
{
void Log(string message);
} public class Logger : ILogger
{
public void Log(string message) { }
}
 
 
发现非公开(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. dict 字典

    Python 学习笔记[dict的操作方法] Python中dict详解

  2. shell 中grep命令详解

    用‘grep’搜索文本文件如果您要在几个文本文件中查找一字符串,可以使用‘grep’命令.‘grep’在文本中搜索指定的字符串.举个例子:假设您正在‘/usr/src/linux/Documentat ...

  3. 用ffmpeg把H264数据流解码成YUV420P

    在网上找了很久这方面的内容,发现网上的代码都太旧了,所使用的函数旧到连最新版本的ffmpeg都已经不包含了,所以对于我这个初学者来说太坑拉.不过经过多次查找ffmpeg的头文件和结合网上的内容,终于成 ...

  4. 移动开发之浅析cocos2d-x的中文支持问题

    题记:这阵子一直在学习cocos2d-x,其跨平台的特性确实让人舒爽,引擎的框架概念也很成熟,虽然相应的第三方工具略显单薄,但也无愧是一件移动开发的利器啊,有兴趣的朋友有时间就多了解吧. 使用引擎的过 ...

  5. 解决Jsoup网页抓取过程中需要cookie的问题

    最近在做城觅网的信息抓取,发现城觅网上海与北京的url是一样的.那怎样才确定信息的来源呢?折腾了半天,才发现城觅网是使用cookie的,如果你把网站的cookie禁用了,就无法在上海与北京之间切换了. ...

  6. PHP的GD库函数大全

    GetImageSize作用:取得图片的大小[即长与宽]  用法:array GetImageSize(string filename, array [imageinfo]); ImageArc作用: ...

  7. u-boot 源码修改 bootcmd,IP ,BOOTARGS等参数

    uboot1.1.6\include\configs\smdk6410.h #define CONFIG_BOOTCOMMAND"nand read 0xc0008000 0x200000 ...

  8. 【转】使用NetBeans和Eclipse开发PHP应用程序

    [51CTO独家特稿]各位用户如果单独看NetBeans和Eclipse的市场占有率,你可能会认为使用其中任何一种IDE开发PHP应用程序都没有 问题,例如: 1.NetBeans:一款开源的集成开发 ...

  9. linux下查看硬件配置的相关命令

    from:http://www.jakee.cn/index.php/archives/501.html 常用命令整理如下:查看主板的序列号: dmidecode | grep -i ’serial ...

  10. Hadoop的partitioner、全排序

    按数值排序 示例:按气温字段对天气数据集排序问题:不能将气温视为Text对象并以字典顺序排序正统做法:用顺序文件存储数据,其IntWritable键代表气温,其Text值就是数据行常用简单做法:首先, ...