首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

MEF 程式設計指南(八):部件生命週期管理與建立原則深度解析

     編輯:關於.NET

在 Managed Extensibility Framework (MEF) 中,每個可動態組合的導出部件都擁有其生命週期。若無特殊需求,開發者通常不會顯式管理生命週期,但 MEF 實際上已為每個部件提供預設的生命週期管理機制。MEF 定義了三種建立原則:Any、Shared 與 NonShared,對應 System.ComponentModel.Composition.CreationPolicy 列舉:

namespace System.ComponentModel.Composition
{
    public enum CreationPolicy
    {
        Any = 0,
        Shared = 1,
        NonShared = 2,
    }
}
  • Any:由 MEF 容器根據請求需求自動決定是否共享實例。
  • Shared:共享部件,同一實例可在多個組合容器中重用(單例模式)。
  • NonShared:非共享部件,每次請求都會建立新的物件實例。

透過 [PartCreationPolicy] 屬性即可為部件指定生命週期。以下範例展示三種原則套用於實作 IBookService 的不同類別:

public interface IBookService
{
    string GetBookName();
}

[PartCreationPolicy(CreationPolicy.Any)]
[Export(typeof(IBookService))]
public class MEFBookService : IBookService
{
    public string GetBookName() => "《MEF程式設計指南》";
}

[PartCreationPolicy(CreationPolicy.NonShared)]
[Export(typeof(IBookService))]
public class ASPNETBookService : IBookService
{
    public string GetBookName() => "《ASP.NET專案案例》";
}

[PartCreationPolicy(CreationPolicy.Shared)]
[Export(typeof(IBookService))]
public class SLBookService : IBookService
{
    public string GetBookName() => "《Silverlight高階程式設計》";
}

導入端的建立原則篩選

在導入端,可使用 [ImportMany] 搭配 RequiredCreationPolicy 參數,只匯入符合特定生命週期的部件:

public partial class MainPage : UserControl
{
    [ImportMany(RequiredCreationPolicy = CreationPolicy.Shared)]
    public List<IBookService> Services { get; set; }

    public MainPage()
    {
        InitializeComponent();
        CompositionInitializer.SatisfyImports(this);
        // 僅會獲得 Shared 與 Any 兩個部件(Any 可視為可共享)
        int count = Services.Count; // 結果為 2
    }
}

這與自訂中繼資料篩選類似,但生命週期篩選是由 MEF 內建機制直接支援,無需額外撰寫篩選邏輯。實務上應根據場景選擇:單例服務用 Shared、狀態獨立的元件用 NonShared、不確定時用 Any 讓容器決定。

容器本身的生命週期與資源釋放

除了部件生命週期,容器本身的資源管理同樣重要。MEF 建議可導入部件實作 IDisposable,當部件從容器移除時,對應資源會自動清理。需注意:組合容器釋放後,延遲載入操作將無法繼續,會拋出 ObjectDisposedException。

MEF 容器階層結構圖

MEF 容器的階層架構

MEF 容器具有階層結構,最上層為應用程式層級容器,可透過 AssemblyCatalog 與 CompositionContainer 建立:

var catalog = new AssemblyCatalog(typeof(MainPage).Assembly);
var container = new CompositionContainer(catalog);

子容器通常掌管可動態組合的部件子集。例如使用 FilteredCatalog 從父容器目錄中依中繼資料篩選,再建立子容器:

var catalog = new AssemblyCatalog(typeof(MainPage).Assembly);
var parent = new CompositionContainer(catalog);

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>();

此架構讓大型應用能將部件依功能域隔離在不同子容器,既保持鬆耦合,又能精確控制生命週期與可見範圍。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved