標籤:
前言
在前面的介紹中我們已經知道:匯入和匯出的匹配成功需要ContractType,ContractName,Metadata都匹配,這裡我們還要介紹一個新的東西:建立策略(creation policy )。有時候我們在容器中的執行個體在每一個匯入之間共用,即單例;有時候我們需要讓每一個匯入都擁有一個各自的執行個體,這在MEF中就是有建立策略決定的。
生命週期(Life Cycle),每一個MEF的組件在容器中都有自己的生命週期,何時建立,何時釋放等。本文就主要介紹一下MEF中得建立策略和生命週期
建立策略
建立策略,其實就是組合容器決定如何建立組件。在組合容器組合組件時,如果匯入和匯出匹配成功,則組合容器會將匯入成員的值設定成為匯出的執行個體。因此,匯出組件的建立策略決定了組件來源於何處:是現有執行個體還是新執行個體。
MEF的建立策略有:Shared(共用)和NonShared(非共用)。
使用Shared建立策略的組件將在每一個匯入組件中共用執行個體。僅當容器中沒有該組件的執行個體時才會建立新執行個體。使用共用策略建立的組件可以是提供服務的組件,以及較佔用記憶體的組件。他們的內部狀態應該儘可能少得受外界影響。
使用NonShared策略的組件在匹配每一個匯入時都會有新的執行個體。這些組件的內部狀態都是相互獨立的,當某些組件需要保持特定的狀態時可以使用這種策略。
MEF關於建立策略提供的特性有3種:Shared,NonShared,Any(請注意Any和Shared的區別,建立策略只有兩種)。匯入和匯出的預設值都是Any。當匯入匯出都是用預設建立策略,或者都是用預設,MEF將預設建立策略為Shared。建立策略的匹配與否也決定了匯出組件和匯入能否成功匹配。以下情況可視為匹配成功:
1. 標記為Any的匯出組件與Shared和NonShared的匯入均能成功匹配;
2. 建立策略為Shared或NonShared的匯出以及標記為Any的匯入匹配成功;
3. 建立策略為Shared的匯出只能與建立策略為Shared和標記為Any匹配成功;
4. 建立策略為NonShared的匯出只能為Shared和標記為Any的匯入匹配成功。
注意:
MSDN是這麼表述的:
匯入和匯出的預設值均為 Any。
指定 Shared 或 NonShared 的匯出將僅與指定相同值或指定 Any 的匯入匹配。
同樣,指定 Shared 或 NonShared 的匯入將僅與指定相同值或指定 Any 的匯出匹配。
如果匯入和匯出均指定 Any,或者未指定建立策略那麼預設為 Any,則建立策略將預設為“共用“。
建立策略特性的用法:
//匯入組件
[Import(RequiredCreationPolicy = CreationPolicy.Shared)]
//匯出組件
[PartCreationPolicy(CreationPolicy.NonShared)]
請看一個簡單的例子:
//定義匯出組件,建立策略為非共用[Export][PartCreationPolicy(CreationPolicy.NonShared)]public class FileLog{ public void WriteLog() { Console.Writeline("This is FileLog!"); }}//定義匯出組件,建立策略為非共用[Export][PartCreationPolicy(CreationPolicy.Shared)]public class DBLog{ public void WriteLog() { Console.Writeline("This is DBLog!"); }}public class MyClass{ //成功匹配 [Import(RequiredCreationPolicy = CreationPolicy.NonShared)] public FileLog MyFileLog1; //匹配失敗 [Import(RequiredCreationPolicy = CreationPolicy.Shared)] public FileLog MyFileLog2; //匹配成功 [Import] public DBLog MyDBLog;}View Code
註:到目前為止我們可以知道影響匯出組件同匯入組件成功匹配的主要因素大概有:ContractType(協定類型),ContractName(協定名稱),Metadata(中繼資料),CetationPolicy(建立策略)。
生命週期
在MEF中,生命週期是比較複雜的,在MSDN中也只用一句話帶過:
由於組件承載於組合容器中,因此其生命週期可能比普通對象更複雜。 組件可實現兩個重要的生命週期相關介面:IDisposable 和 IPartImportsSatisfiedNotification。
容器本身實現了IDisposable,在容器Dispose方法被調用時,容器會對容器中得每一個組件調用Dispose方法。一般情況下,組件只有在容器釋放時才會釋放資源。聯想到上面介紹的建立策略,有人不禁要問如果建立策略為非共用的組件過多,很佔用很多資源,不過不用擔心:容器提供了 ReleaseExport 方法。此方法可以釋放匯出組件,並對組件佔用的資源進行釋放。
如果組件實現了介面IPartImportsSatisfiedNotification ,當組合已完成並且組件的匯入可供使用時,組合視窗將對組件調用介面中得方法OnImportsSatisfied。
IPartImportsSatisfiedNotification 包含一個名為 OnImportsSatisfied 的方法。 當組合已完成並且組件的匯入可供使用時,組合視窗將對實現介面的任何組件調用此方法。 組件是組合引擎建立,用於滿足其他組件的匯入。 在設定好組件的匯入之前,您無法執行任何依賴於組件建構函式中的匯入值或對這些值進行操作的初始化,除非已通過使用 ImportingConstructor 特性將這些指定為必備。 此方法通常為首選方法,但在某些情況下,建構函式注入可能不可用。 在這些情況下,可以在 OnImportsSatisfied 中執行初始化,並且組件應實現 IPartImportsSatisfiedNotification。
靈活運用組件的生命週期在具體使用MEF中會有很大得協助,如:我們可能將WCF,EF做成組件,然後使用MEF整合這些組件,那麼在組合成功後,我們可能需要讀取WCF配置發布服務,或者讀取DB.config建立資料庫連接等。這時在OnImportsSatisfied 中完成這些操作可能效果更好。
http://www.cnblogs.com/pszw/archive/2011/12/14/2286895.html
建立策略(Creation Policy )和生命週期(Life Cycle)