.NET 4.5 MEF 基于约定的编程模型

Managed Extensibility Framework .NET 4.5中有若干改进,这些都是源自于开源社区的推动(http://mef.codeplex.com/)。

这改动包括:对泛型类型的支持、多作用域对基于约定编程模型的支持。

什么样的代码才算是基于约定的呢,其实在MS其它框架中也有所体现,比如ASP.NET MVC Url Routing /EF 4.1+Fluent API的配置方式都可以算做基于约定的。

话说MEF之前是用声明式的Attribute来搞定代码的:

 1  class Util
 2     {
 3         [Import]
 4         public SubUtilA A { get; set; }
 5         [Import]
 6         public SubUtilB B { get; set; }
 7     }
 8     [Export]
 9     class SubUtilA { }
10     [Export]
11     class SubUtilB { }

这样写当然没有什么问题,Attribute的形式看起来也很清爽,但是这样写总会有些问题:

  1. 扩展更多类型时总是要加上ExportImportAttribute
  2. 看起来类不是那么纯了,特别是处女座的同学

那么.NET 4.5中基于约定的模型可以让我们怎么来搞定这俩问题呢?

1     class Util
2     {
3         public SubUtilA A { get; set; }
4         public SubUtilB B { get; set; }
5     }
6     class SubUtilA { }
7     class SubUtilB { }

这些是类型定义,我们不添加Attribute

然后里,我们定义一个约定

1           var builder = new RegistrationBuilder();
2             builder
3                 .ForTypesMatching(c => c.Name.StartsWith("SubUtil"))
4                 .Export();
5             builder
6                 .ForType<Util>()
7                 .Export()
8                .ImportProperties(c => c.Name.Length == 1);

嗯,导出所有SubUtil开头的类,然后在UtilImport所有长度是1的属性

通过这样简单的规则,在再次添加新的类型的时候就可以不额外添加或改动多余代码了。

 

当然,这种规则定义还可以更加多彩,有待你发现

ALL Code:

View Code
 1 using System;
 2 using System.Collections.Generic;
 3 using System.ComponentModel.Composition;
 4 using System.ComponentModel.Composition.Hosting;
 5 using System.ComponentModel.Composition.Registration;
 6 using System.Linq;
 7 using System.Text;
 8 using System.Threading.Tasks;
 9 
10 namespace ConsoleApplication1
11 {
12     class Program
13     {
14         static void Main(string[] args)
15         {
16             var builder = new RegistrationBuilder();
17             builder
18                 .ForTypesMatching(c => c.Name.StartsWith("SubUtil"))
19                 .Export();
20             builder
21                 .ForType<Util>()
22                 .Export()
23                .ImportProperties(c => c.Name.Length == 1);
24             var cat =
25                 new AssemblyCatalog(typeof(Program).Assembly, builder);
26             var container = new CompositionContainer(cat);
27 
28             var u = container.GetExportedValue<Util>();
29             Console.ReadKey();
30 
31         }
32     }
33 
34     class Util
35     {
36         public SubUtilA A { get; set; }
37         public SubUtilB B { get; set; }
38     }
39     class SubUtilA { }
40     class SubUtilB { }
41 
42 
43     //class Util
44     //{
45     //    [Import]
46     //    public SubUtilA A { get; set; }
47     //    [Import]
48     //    public SubUtilB B { get; set; }
49     //}
50     //[Export]
51     //class SubUtilA { }
52     //[Export]
53     //class SubUtilB { }
54 
55 }

 

 

posted @ 2012-08-09 13:31  重典  阅读(3589)  评论(8编辑  收藏  举报