DotNet 4 学习笔记之 1-------------MEF (Managed Extensibility Framework)

.net 4 和对应的vs2010已经出来一阵子了.从最早的beta1到如今的RC,已愈发向正式版靠拢.

最近闲来无事,又似乎有些假日综合症之嫌,于是静下心来对dotnet 4.0从头到底好好研究一下. 

首先我们来研究MEF 。

 所谓MEF (Managed Extensibility Framework)

通常,由于应用需求的变化频繁,导致应用软件可扩展性越做越差,很难加入新的功能.在NET4.0中,加入了MEF(托管可扩展框架)就为了解决了简化可扩展应用程序和组件的设计这个问题.

由于MEF已经包含在.net 4.0之中,我们不需要额外下载其类库,当然,如果对其实现原理感兴趣,可以在http://www.codeplex.com/MEF看到其源代码.

 

如何创建一个MEF Application

通常,创建一个MEF Application需要实现以下几个步骤.

  1. 使用[Import]属性标记可扩展的地方,并将其已接口形式表达
  2.  创建进行扩展的组件,实现(1)的接口的同时使用[Export]标记

 

我们接着用一个简单的例子来做以上2步。

首先,我们申明了一个可用于扩展的属性Message,并实现了其调用时的方法Do().

注意,Import属性是在System.ComponentModel.Composition下,需要在项目中引入System.ComponentModel 

    class MEFTest
    {
        [Import]
        
public string Message { getset; }
        
public void Compose()
        {
            CompositionContainer container 
= new CompositionContainer();
            CompositionBatch batch 
= new CompositionBatch();
            batch.AddPart(
new Extension1());
            batch.AddPart(
this);
            container.Compose(batch);
        }
        
public void Do()
        {
            Console.WriteLine(Message);
            Console.ReadKey();
        }
    }

 

 接着,我们要具体实现一个被扩展的对象。

 class Extension1
    {
        [Export]
        
public string Message
        {
            
get
            {
                
return "I am extension 1";
            }
        }
    }

  这样,在我们需要正式初始化MEFTest实例并调用其Do方法之前,自然需要一个方法将可扩展的Message对象“绑定”到Message这个接口之上。而这就是 Compose()方法的作用。在其之中,我们创建了一个CompositionContainer容器用于绑定该属性。

请注意,任何Export标记过的都必须有对应的Import在容器中,反之却可以通过 Compose()。

 关于实际应用

 通常,我们在实际应用中没有上文来的这么简单。MEF支持通过程序集或目录(DirectoryCatalog)或2者结合等方式绑定可扩展的对象。

 CompositionContainer  container = new CompositionContainer(

new DirectoryCatalog(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)));

 

 如果在新建CompositionContainer容器时,使用了DirectoryCatalog,则在该目标路径下的所有程序集都会被遍历查询,用于寻找实现Import接口的具体class。

 当然,请在标记Export时使用[Export(typeof(接口))]来精确定位。

 另外,通常使用时,我们需要使用一些特定的元数据(metadata)来进一步描述或说明某些特定接口(如果安全性,速度等)。我们可以使用PartMetadata标记class,使用ExportMetadata标记实现方法。 

 

总结

 本文主要介绍了何为MEF,以及MEF的简单应用。望广大网友指正。

 To Be Continue....

 

-----------------------------------------------------------------------------------------------------------------

| 戴佳顺 | msn:edwin19861218@hotmail.com | QQ:1961218 | Web:http://www.dumuzi.cn |

标签: .net, .net 4.0, MEF
posted @ 2010-02-22 16:26 Edwin Tai 阅读(2847) 评论(7) 编辑 收藏

 回复 引用 查看   
#1楼2010-02-23 07:27 | Muse      
我刚好从前天开始学习MEF,还没找到很详细的MEF介绍文章呢。

 回复 引用 查看   
#2楼[楼主]2010-02-23 09:16 | Edwin Tai      
@Muse
我怎么看这东西都和ioc差不多

 回复 引用 查看   
#3楼2010-02-23 10:39 | Ariex      
@Edwin Tai
印象这个项目是cnblogs里面的一个人最先发起的,记得当时文章里面提到这个的特点就是基于属性的IOC框架

 回复 引用 查看   
#4楼[楼主]2010-02-23 12:55 | Edwin Tai      
@Ariex
很奥妙的是,ms的人似乎不以为然.
BUT COULDN’T I ACCOMPLISH THIS WITH REFLECTION/DEPENDENCY
INJECTION/IOC CONTAINERS/VOODOO?
There is overlap in the functionality provided by the above technologies and MEF. MEF and IOC do have some
overlap, and many would classify MEF as an IOC. MEF’s primary purpose is, however, creating extensible
applications through discovery and composition, whereas IOC containers are generally more focused on
providing an abstraction for testing purposes. It’s not a discussion I want to get into, but Oren does, so please
refer to: http://ayende.com/Blog/archive/2008/09/25/the-managed-extensibility-framework.aspx.

 回复 引用 查看   
#5楼2010-02-26 12:09 | Muse      
引用Edwin Tai:
@Muse
我怎么看这东西都和ioc差不多

我是这方面的新手,没研究过ioc,所以根本谈不上差什么。

这两天研究结果,发现一个问题:
扩展模块只能创建出一个实例,比如扩展一个菜单功能,效果就是简单的打开一个自建的窗口,第一次点击菜单创建了一个控件就是自建的窗口,但第二次点击菜单时,就不创建控件了,而是直接指向第一次创建的那个控件。
目前发现的方法就是重新创建Container,再用新的Container创建控件,不过总觉得这种方式不对,但又没发现什么办法解决这个问题。(试了CreationPolicy,没效果)

 回复 引用 查看   
#6楼2010-03-24 11:33 | 疯流成性      
试了下,的确有很多可以幻想的使用场合。
 回复 引用 查看   
#7楼2011-09-14 15:36 | 有趣之极      
呵呵,插件机制用这个来实现比较简单