组合部件通过 [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. RAID0_RAID1_RAID10_RAID5各需几块盘才可组建

    RAID 0 RAID 0即Data Stripping(数据分条技术).整个逻辑盘的数据是被分条(stripped)分布在多个物理磁盘上,可以并行读/写,提供最快的速度,但没有冗余能力.要求至少两个 ...

  2. 【转】Github轻松上手1-Git的工作原理与设置

    转自:http://blog.sina.com.cn/s/blog_4b55f6860100zzgp.html 作为一个程序猿,如果没有接触过stack overflow和Github,就如同在江湖中 ...

  3. Oracle 课程八之性能优化之10053事件

    一. 10053事件 当一个SQL出现性能问题的时候,可以使用SQL_TRACE 或者 10046事件来跟踪SQL. 通过生成的trace来了解SQL的执行过程. 我们在查看一条SQL的执行计划的时候 ...

  4. java web 学习十四(JSP原理)

    一.什么是JSP? JSP全称是Java Server Pages,它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术. JSP这门技术的最大的特点在于,写jsp就像在写h ...

  5. Delphi TRichEdit加载word内容

    procedure TForm1.btn6Click(Sender: TObject);var WordApp: Variant; //声明一个word对象beginWordApp := Create ...

  6. Ubuntu 14.04配置FTP服务器

    搭建: 1.sudo apt-get update                                        #更新软件 2.sudo apt-get install vsftpd ...

  7. switchomega配置

  8. [CODEVS1697]⑨要写信

    题目描述 Description 琪露诺(冰之妖精)有操控冷气的能力.能瞬间冻结小东西,比普通的妖精更危险.一直在释放冷气的她周围总是非常寒冷. 由于以下三点原因…… 琪露诺的符卡 冰符“Icicle ...

  9. document.write("\x3c\x54")?是加密了吗?

    <script>document.writeln("\x3C\x73\x63\x72\x69\x70\x74\x20\x73\x72\x63\x3D\x22\x48\x54\x5 ...

  10. linux查看端口信息以及关闭进程

     lsof -i:6633 查看端口6633的使用情况 kill  (+PID数值),结束进程