可组合部件(Composable Parts)
 
在 MEF 内部可组合部件是一个可组合单元。可组合部件导出其他可组合部件需要的服务,并且从其他可组合部件导入服务。在 MEF 编程模型中,可组合部件用 [System.ComponentModel.Composition.Import] 和 [System.ComponentModel.Composition.Export] 特性标识,以便声明导出点和导入点。可组合部件应该包含至少一个导出点。可组合部件要么显式添加到容器或者通过使用目录创建。MEF 访问默认目录识别 Export 特性标识的可组合部件。
 
 
契约(Contacts)
 
可组合部件不直接依赖另一个,相反依赖字符串标识的契约。每个导出点享有一个契约,并且每个导入点申明的他所需的契约。容器利用契约信息在导入点和导出点之间做匹配。如果没有指定契约,MEF 会隐式使用完全限定名的契约类型。如果传递了类型,也会使用完全限定名。
 
注意:默认情况下通过类型传递给契约。尽管契约可以是任意字符串,但是可能导致歧义(Ambiguity)。比如:“Sender”可能与另一个库的“Sender”实现重叠。基于这个原因,如果需要指定字符串的契约,强烈建议契约名应该包括公司名的限定命名空间,例如:“Contoso.Exports.Sender”。
 
以下代码片段,所有导出契约是等价的(Equivalent)。
 
    [Export]
public class Exporter { } [Export(typeof(Exporter))]
public class Exporter1 { } [Export("Chapter02.Exporter")]
public class Exporter2 { }
接口/抽象契约
针对可组合部件的一种常见模式是导出接口或者抽象类型,而不是一个具体的类型。这允许导入者完全从特定的导出实现中解耦,这导致关注点的分离。例如:下面可以看到两种导出 IMessageSender 的 Sender 实现。Notifier 类导入 IMessageSender 集合,调用他的 Send() 方法。新的 MessageSender 可以很容易添加到系统。

 
 
    [Export(typeof(IMessageSender))]
public class EmailSender : IMessageSender
{
public void Send(string message)
{
Console.WriteLine("Invoke EmailSender Send() method");
Console.WriteLine(message);
}
} [Export(typeof(IMessageSender))]
public class TCPSender : IMessageSender
{
void IMessageSender.Send(string message)
{
Console.WriteLine("Invoke TCPSender Send() method");
Console.WriteLine(message);
}
} public interface IMessageSender
{
void Send(string message);
}
 
契约程序集(Contract Assemblies)
 
使用 MEF 构建可扩展应用程序时的常见模式是发布契约程序集。契约程序集仅包含使用者可以扩展应用程序的契约类型。通常是接口,但是也可能是抽象类。另外,契约程序集包含导入点使用的元数据(Metadata)视图接口,以及任何自定义 MEF 导出特性。

 
注意:你必须指定特定的存在的导出接口类型(IMessageSender),否则类型(EmailSender)本身将被导出。
 
原文地址:

MEF 编程指南(二):定义可组合部件和契约的更多相关文章

  1. MEF初体验之二:定义组合部件和契约

    组合部件 在MEF中,一个组合部件就是一个组合单元,组合部件"出口"其它组合部件需要的服务并且从其它部件"进口"需要的服务.在MEF编程模型中,为了声明组合部件 ...

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

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

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

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

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

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

  5. SQL编程篇 (二) 定义与流程控制

    分类: sql编程:标准的sql 编程 * 纯sql 在标准的编程中又分为 sqlserver-->T-sql oracle-->pl-sql(扩展) 变量:在使用变量之前先定义 声明变量 ...

  6. MEF 编程指南(八):过滤目录

    当使用子容器的时候,基于特定的标准(Specific Criteria)过滤目录是很必要的.比如,基于部件构造策略的过滤器是很常见的.下面的代码片段演示了如何构建的特殊途径(Particular Ap ...

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

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

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

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

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

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

随机推荐

  1. Android SharedPreferences 权限设置

    说明: 由于目前打算采用两个app来完成一件事,采用SharedPreferences来做数据交换,于是突然想验证一下Java层的权限设置会不会就是设置Linux下文件的权限,验证的结果是这样的. T ...

  2. Math.trunc

  3. html5极速3D立体式图片相册切换效果

    下载Demo  

  4. 云计算服务模型,第 3 部分: 软件即服务(PaaS)

    英文原文:Cloud computing service models, Part 3: Software as a Service 软件即服务 (SaaS) 为商用软件提供基于网络的访问.您有可能已 ...

  5. MyBatis association的两种形式——MyBatis学习笔记之四

    一.嵌套的resultMap 这 种方法本质上就是上篇博文介绍的方法,只是把教师实体映射从association元素中提取出来,用一个resultMap元素表示.然后 association元素再引用 ...

  6. ThinkAndroid是简洁,快速的进行Android应用程序的框架

    ThinkAndroid简介ThinkAndroid是一个免费的开源的.简易的.遵循Apache2开源协议发布的Android开发框架,其开发宗旨是简单.快速的进行Android应用程序的开发,包含A ...

  7. golang语言部分保留字的举例

    golang和c的代码有很大不同的,一不小心就会误用. 1 /* go保留字: */ /* break default func interface select case defer go map ...

  8. 11、WebView 使用总结

    <WebView android:id="@+id/webview" android:background="@color/white" android: ...

  9. [转]解决crystal report水晶报表在浏览器提示bobj未定义的错误

    网上的中文文章(比如这篇文章)都是写的部署到服务器后出现的问题,同时也指出要把crystal report的aspnet_client文件夹拷贝到对应项目的根目录里,这样就可以正常显示了,但是具体到我 ...

  10. JDBC获取表的主键

    JDBC获取表的主键 案例,创建订单,并根据订单号向订单明细表插入数据 sql语句: 创建两表 create table orders(  id number(4) primary key,  cus ...