MEF程序設(shè)計(jì)指南八:部件生命周期(Parts Lifetime)托管
{
public enum CreationPolicy
{
Any = 0,
Shared = 1,
NonShared = 2,
}
}
Any表示可共享或不共享,部件的實(shí)例用MEF容器根據(jù)不同的請(qǐng)求需求自動(dòng)控制;Shared表示共享部件,既Shared類型的插件部件可以在多個(gè)MEF組合容器中共用;其次是NonShared類型,表示不共享部件實(shí)例,每當(dāng)有新的請(qǐng)求就會(huì)創(chuàng)建一個(gè)新的對(duì)象實(shí)例。在MEF中,通過PartCreationPolicyAttribute特性實(shí)現(xiàn)對(duì)部件的生命周期配置。
{
string GetBookName();
}
[PartCreationPolicy(CreationPolicy.Any)]
[Export(typeof(IBookService))]
public class MEFBookService : IBookService
{
public string GetBookName()
{
return "《MEF程序設(shè)計(jì)指南》";
}
}
[PartCreationPolicy(CreationPolicy.NonShared)]
[Export(typeof(IBookService))]
public class ASPNETBookService : IBookService
{
public string GetBookName()
{
return "《ASP.NET項(xiàng)目案例》";
}
}
[PartCreationPolicy(CreationPolicy.Shared)]
[Export(typeof(IBookService))]
public class SLBookService : IBookService
{
public string GetBookName()
{
return "《Silverlight高級(jí)編程》";
}
}
如上示例代碼分別演示了使用Any、Shared及NonShared類型的生命周期托管類型對(duì)不同的對(duì)象進(jìn)行導(dǎo)出部件配置。接下來通過導(dǎo)入部件并加入生命周期托管篩選,詳細(xì)應(yīng)用如下代碼塊所示:
{
[ImportMany(RequiredCreationPolicy = CreationPolicy.Shared)]
public List<IBookService> Service { get; set; }
public MainPage()
{
InitializeComponent();
CompositionInitializer.SatisfyImports(this);
//得到成功裝配的部件總數(shù)為2,因?yàn)锳ny類型是可以共存于多個(gè)MEF容器的。
int count = Service.Count;
}
}
表面上看去和上一篇指南中介紹的部件的篩選過濾功能非常相似,不同是的過濾篩選是通過自定義篩選策略實(shí)現(xiàn),而這里是通過MEF生命周期范圍托管來實(shí)現(xiàn)的。在實(shí)際的項(xiàng)目開發(fā)中需根據(jù)不同的應(yīng)用場(chǎng)景確定具體的技術(shù)實(shí)現(xiàn)方案。
除了容器部件的生命周期托管,我們也得考慮部件容器自身的生命周期,容器什么時(shí)候釋放資源,時(shí)候時(shí)候釋放其內(nèi)部部件的資源占用等。為了提高系統(tǒng)的整體性能,MEF建議將每一個(gè)可導(dǎo)入部件實(shí)現(xiàn)IDisposable 接口,用于資源的占用處理,如果部件從MEF容器中移除那么所對(duì)應(yīng)占用的資源也會(huì)自動(dòng)的清理。這里需要注意一點(diǎn),就是當(dāng)組合容器被釋放掉后遲延加載的操作就不能再繼續(xù)工作了,會(huì)拋出System.ObjectDisposedException異常。

如上圖所示,MEF的容器是具有層次結(jié)構(gòu)的,最高層級(jí)容器為程序直接應(yīng)用級(jí)容器,可以通過以下的代碼獲取到。
var container = new CompositionContainer(catalog);
位于頂級(jí)容器之下的子容器,通常來說都是控制著一些可動(dòng)態(tài)裝配的部件對(duì)象,如同上一篇指南中介紹到使用過濾器篩選部件的應(yīng)用案例,通過過濾表達(dá)式從頂級(jí)容器中進(jìn)行篩選,得出了新的MEF容器child,child托管著根據(jù)條件過濾篩選出來的所有結(jié)果部件對(duì)象。詳細(xì)代碼如下:
var catalog = new AssemblyCatalog(typeof(MainPage).Assembly);
//將目錄裝載進(jìn)MEF組合容器
var parent = new CompositionContainer(catalog);
//通過元數(shù)據(jù)過濾篩選出元數(shù)據(jù)名稱為"UC"值為"CC"的組合部件
var filteredCat = new FilteredCatalog(catalog,
def => def.Metadata.ContainsKey("UC") &&
def.Metadata["UC"].ToString() == "CC");
var child = new CompositionContainer(filteredCat, parent);
var control = child.GetExportedValue<UserControl>();
MEF官方網(wǎng)站:http://mef.codeplex.com/
推薦指南:MEF程序設(shè)計(jì)指南一:在應(yīng)用程序中宿主MEF
MEF程序設(shè)計(jì)指南二:Silverlight中使用CompositionInitializer宿主MEF
MEF程序設(shè)計(jì)指南三:MEF中組合部件(Composable Parts)與契約(Contracts)的基本應(yīng)用
MEF程序設(shè)計(jì)指南四:使用MEF聲明導(dǎo)出(Exports)與導(dǎo)入(Imports)
MEF程序設(shè)計(jì)指南五:遲延(Lazy)加載導(dǎo)出部件(Export Part)與元數(shù)據(jù)(Metadata)
MEF程序設(shè)計(jì)指南六:MEF中的目錄服務(wù)(DeploymentCatalog)
MEF程序設(shè)計(jì)指南七:使用目錄(Catalog)動(dòng)態(tài)裝載xap與目錄篩選(Filtered Catalog)
浙公網(wǎng)安備 33010602011771號(hào)