MEF初体验

.net4.0发布很久了,也早就知道包含了一个叫做MEF的库,但是一直没有亲自试试看,还是有点惭愧的。这两天有些空闲,参考了MSDN和一些博客,简单体验了一下MEF。下面记录了一些要点,作为一段学习笔记吧。

MEF的全称是Managed Extensibility Framework,顾名思义MEF主要是用于解决程序的扩展问题的一个框架。MEF内置在.net Framework 4.0中,因此使用它通常不需要额外的什么程序集(MEF的命名空间是System.ComponentModel.Composition)。MEF本质上和Castle Windsor、Structure Map及Unity样,也是一种IOC容器,但MEF采用了基于Attribute的特性化编程模型,而没有采用基于配置的形式。因为配置文件对于一般用户可能还是过于复杂了。

MEF有两个核心的概念:导入与导出。导入是指可扩展的点,需要其他的实现来填充这个部分;导出则相反,是指扩展的具体实现,通过MEF的组合将这些实现组装的扩展点上去。导入和导出分别使用 Import 和 Export 特性来声明。

Export 特性可修饰类、字段、属性或方法,而 Import 特性可修饰字段、属性或构造函数参数。

下面是一个小示例。定义一个简单的需求,主程序通过扩展的方式加载一个翻译组件,然后使用翻译组件的翻译一些文字,并将来自翻译组件中的签名信息附加到翻译好的文本后,最后将内容输出。

1、建立一个解决方案,解决方案包括三个项目。控制台应用程序MEFTest,作为主程序;类库MEFTest.Interface,作为接口程序集;另一个类库MEFTest.Implementation作为接口的实现。MEFTest与MEFTest.Implementation均添加对MEFTest.Interface的引用及对MEF框架的引用。

2、在MEFTest.Interface中定义一个翻译器接口ITranslator。

using System;

namespace MEFTest.Interface
{
    public interface ITranslator
    {
        string Translate(string text);
    }
}

 

3、MEFTest作为主程序,主要是提供主逻辑并且提供扩展点。定义一个类

using System;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;

using MEFTest.Interface;

namespace MEFTest
{
    public class TranslationTest
    {
        public TranslationTest()
        {
            var catalog = new AggregateCatalog();
            catalog.Catalogs.Add(new DirectoryCatalog("."));
            var container = new CompositionContainer(catalog);
            container.ComposeParts(this);
        }

        [Import]
        public string Sign { get; set; }

        [Import]
        public ITranslator Translator { get; set; }
    }
}

这个类中提供了两个导入(扩展点),Translator用来扩展翻译器,Sign用于签名。在构造方法在首先初始化了一组目录对象Catalog(目录对象采用组合模式实现,这里实例化了一个聚和目录AggregateCatalog,并且在聚和目录中添加了一个基于文件夹查找扩展组件的DirectoryCatelog。当TranslationTest类初始化时,MEF将在DirectoryCatelog设定的文件夹下查找扩展组件,本例是当前文件夹),然后用Catalog构造一个container对象,最后由container完成组合。

 

4、在MEFTest.Implementation中实现ITranslator接口,并且将这个实现类标记为导出,这是一个类型的导出。

using System;
using System.ComponentModel.Composition;

using MEFTest.Interface;

namespace MEFTest.Implementation
{
    /// <summary>
    /// 具体的计算算法实现
    /// </summary>
    [Export(typeof(ITranslator))] //导出
    public class Translator : ITranslator
    {
        public string Translate(string text)
        {
            //假设这里有一个非常强大的翻译算法
            return "Promise more, not to be, that is just a lie.";
        }
    }
}

5、在MEFTest.Implementation中添加一个Settings的类用于实现签名。将Sign字段标记为导出,这是一个字段的导出。

using System;
using System.ComponentModel.Composition;

namespace MEFTest.Implementation
{
    public class Settings
    {
        [Export]
        public string Sign = "by MEFTestTranslator";
    }
}

6、最后,在main方法中添加一些代码将上面的类串联起来。

using System;

namespace MEFTest
{
    class Program
    {
        static void Main(string[] args)
        {
            TranslationTest tester = new TranslationTest();

            string result = tester.Translator.Translate("承诺再多,做不到,那也只不过还是谎言。");
            Console.WriteLine(result + "——" + tester.Sign);
            Console.ReadKey();
        }
    }
}

7、生成解决方案,记得将MEFTest.Implementation 生成的dll,拷贝到主程序所在的文件夹中。运行主程序,显示如下结果。

image

这个例子非常的简单,很多MEF的特性都没有利用的到,下面这些参考资料比较详细的讲述了MEF的各项特性,有兴趣可以学习一下。

参考资料

http://www.cnblogs.com/pszw/category/335788.html —— 我学MEF系列

http://www.cnblogs.com/beniao/archive/2010/08/11/1797537.html —— MEF程序设计指南

http://msdn.microsoft.com/zh-cn/library/dd460648 —— Managed Extensibility Framework 概述(MSDN)

http://msdn.microsoft.com/zh-cn/library/ee155691.aspx#MtViewDropDownText —— 特性化编程模型概述(MSDN)

http://msdn.microsoft.com/zh-cn/magazine/ee291628.aspx —— 在 .NET 4 中使用托管可扩展性框架构建可组合的应用程序(MSDN杂志)

posted @ 2012-08-02 11:44  宽厚  阅读(411)  评论(0编辑  收藏  举报