Electronic Joint Business

Solution for E-Business

mef

深入MEF框架 (二)契约与导入、导出

契约
所谓的契约即一种约定,或者叫做规则。在上一节的例子中,在对象 StringProvider 中就定义了一个导出部件属性(Output),并为其指定了通信契约为“Message”。这里的 “Message” 就是种约定,即:在需要使用到这个属性的地方,都可以利用 [Import] 引用契约(“Message”)进行部件的导入。

在 MEF 中可组合部件并非是直接依赖于彼此,它们都依赖于一个契约,也就是一个标示字符串。每个导出都有一个契约,而导入需要声明它需要依据哪个契约。容器通过使用契约信息来匹配导入和导出。如果没有指明契约,MEF 默认使用类型的全限定名作为契约。实际上这一步可以简单的理解为“依赖注入”,本质上就是对象的实例初始化过程。如果在导出中指定了类型,MEF 则会使用该类型全限定名。

注意:对于非基本类型,默认情况下,应该使用类型而不建议使用字符串在作为契约。虽然契约可以是字符串,但可能会导致一些混淆。比如 “Sender” 这个契约可能与另一个实现里的 “Sender” 重名。因此如果使用字符串作为契约,最好遵循名称空间的写法并带上公司的名字,比如”Contoso.Exports.Sender”。

下面的代码中出现的所有导出契约都是等价的。

namespace MEF.Examples{   
    [Export]   
    public class Exporter {}  
 
    [Export(typeof(Exporter))]  
    public class Exporter{}   
    
    [Export("MEF.Examples.Exporter")]   
    public class Exporter{}   
}

可组合部件的普遍模式是采用接口或者抽象类型来作为契约,而不是具体类型。这样导入部件完全与其导入的导出部件的某个特定实现解耦从而分离关注。比如如下的代码中,有两个类都导出了IMessageSender。Notifier类导入一组IMessageSender,并调用其中每一项的Send()方法。现在新的信息发送器可以很容易的被添加到系统中去。

>>> 阅读全文

 

, ,

深入MEF框架 (一) 基本概念

文章评分:

为什么需要 MEF?
近年来,用于实现可扩展性的框架越来越受到人们的重视,为此已经存在许多依赖注入框架来解决应用的扩展性问题,比如 Eclipse 的 OSGI 实现以及 Java 的 Spring 等等。在 Microsoft 的平台上,.NET Framework 自身内部包含组件模型和 System.Addin,此外还有不少开源解决方案,包括 SharpDevelop 的 SODA 体系结构和“控制反转”容器(如 Castle Windsor、Structure Map、Spring.Net 以及 Unity )。为什么我们还需要 MEF 呢?

在 Microsoft 看来,这些方案有些过于庞杂(比如 OSGI ),有些则需要开发人员完成许多额外配置工作(比如 Spring ), MEF 试图秉承这些解决方案的优点,尝试解决刚才所提及的令人头痛的问题。 MEF 有两个优点:

  • 第一,MEF是开源项目,其源代码在Codeplex上可以下载,
  • 第二,MEF 是第一个随 CLR 发布的扩展性管理的框架,而且在 Visual Studio 和 Silverlight 中被广泛应用。

官方给 MEF 下的定义:Managed Extensibility Framework(MEF)是 .NET 平台下的一个扩展性管理框架,它是一系列特性的集合,包括依赖注入( DI )以及 Duck Typing 等。MEF 为开发人员提供了一个工具,让我们可以轻松的对应用程序进行扩展并且对已有的代码产生最小的影响,开发人员在开发过程中根据功能要求定义一些扩展点,之后就可以使用这些扩展点与应用程序交互;同时MEF让应用程序与扩展程序之间不产生直接的依赖,这样也允许在多个具有相同的扩展需求之间共享扩展程序。

概念
简单说一下 MEF 的工作原理,MEF 的核心包括一个 catalog(目录)和一个 CompositionContainer(组合容器)。catalog 用于发现扩展,而 container 用于协调创建和梳理依赖性。MEF 组合模型的核心是组合容器,该容器包含所有可用的部件并执行组合操作(即,将导入和导出配对)。见下图。

>>> 阅读全文

 

, , , ,