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的形式看起來也很清爽,但是這樣寫總會有些問題:
- 擴展更多類型時總是要加上Export和Import的Attribute
 - 看起來類不是那么純了,特別是處女座的同學
 
那么.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開頭的類,然后在Util中Import所有長度是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 }
