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

MEF (Managed Extensibility Framework) 入門指南與實戰演練

     編輯:關於.NET

什麼是 MEF?

Managed Extensibility Framework (MEF) 讓開發者能在 .NET 應用程式中提供掛鉤,供使用者與第三方擴充。可視為通用應用程式擴充工具。MEF 支援動態創建擴充,無需修改應用程式,亦無需擴充內容相關知識,確保編譯時零耦合,運行時即可擴充、無需重新編譯。MEF 還能在載入擴充前檢視元數據,採用更快速的方式。

核心概念

  • Composition (復合): 將不同功能物件組合為複雜物件的過程,非繼承而是組合。如 Wing、Propeller、Fuselage 組成 Aircraft。
  • ComposableParts: MEF 關鍵構建塊,透過 Exports 與 Imports 公開與使用組件擴充。
  • Contracts: Export 與 Import 組件的通信管道,通常由 Interface 實現,避免依賴與緊密耦合。
  • Conditional Binding: 載入符合特定元數據標準的組件,如僅載入復合石墨材質的 VerticalStabilizer。

主要實現方式:在應用程式擴充點加 Import 屬性,擴充加 Export 屬性。Export 為供應者提供價值,Import 為消費者消費價值。

實驗目標與系統需求

目標: 定義組件可擴充選項、執行條件綁定與組件創建、運行時導入擴充組件。
需求: Visual Studio 2010、.NET Framework 4。

安裝與準備

以管理員權限運行命令列腳本,執行 CheckDependencies.cmd 驗證先決條件並安裝代碼片段。解決方案檔位於 %TrainingKitInstallFolder%\Labs\IntroToMEF\Source\Ex01-DynamicallyAddModules\begin\C#。

練習 1:動態向應用程式添加模組

場景

用戶初始安裝特定模組,後續需添加更多。MEF 可配置應用程式監控已知目錄,自動載入該目錄下的模組組件,無需顯式引用。

任務 1:更新主窗體載入支援模組

  1. 打開 MainForm.cs 代碼視圖。
  2. 添加 MEF 命名空間:using System.ComponentModel.Composition; using System.ComponentModel.Composition.Hosting;
  3. 定義導入集合(置於構造函數上方):
    [ImportMany]
    public Lazy<IMainFormContract, IDictionary<string, object>>[] ImportedMainFormContracts { get; set; }
  4. 創建全域 CompositionContainer:private CompositionContainer _container;
  5. 添加從目錄獲取容器的輔助方法:
    private CompositionContainer GetContainerFromDirectory() {
        var catalog = new AggregateCatalog();
        var thisAssembly = new AssemblyCatalog(Assembly.GetExecutingAssembly());
        catalog.Catalogs.Add(thisAssembly);
        catalog.Catalogs.Add(new DirectoryCatalog(_extensionDir));
        return new CompositionContainer(catalog);
    }
  6. 添加 Compose 方法解析導入導出:
    private bool Compose() {
        _container = GetContainerFromDirectory();
        try { _container.ComposeParts(this); }
        catch (CompositionException ex) { MessageBox.Show(ex.ToString()); return false; }
        return true;
    }
  7. 在構造函數調用 Compose,失敗則關閉窗體。

任務 2:創建擴充模組 (EmployeeMaintenance)

  1. 為 MefEmployeeModule 專案添加 System.ComponentModel.Composition 參考。
  2. 在 EmployeeMaintenance.cs 頂部添加 using System.ComponentModel.Composition;。
  3. 標記類別實現契約並導出:
    [Export(typeof(IMainFormContract))]
    [ExportMetadata("Name", "Employee Pane")]
    [ExportMetadata("MenuText", "&Employees")]
    public partial class EmployeeMaintenance : Form, IMainFormContract
  4. 實現 IMainFormContract 介面屬性 MenuItemText 與 SubFormTitle。
  5. 建置專案。

任務 3:運行時導入 Employee Maintenance 窗體

  1. 在 MainForm_Load 事件中遍歷導入集合,根據元數據動態添加選單項並掛鉤點擊事件。
  2. 實現 LaunchModule_Click 透過元數據匹配啟動對應表單。

驗證步驟

  1. 配置 Post-Build 事件將輸出複製到 ExtModules 目錄。
  2. 建置方案,設置 MefLabMain 為啟動專案,按 F5 運行。初始 Modules 選單為空。
  3. 退出,更新 Post-Build 複製模組組件,再次運行。Employees 選單項出現,點擊彈出 Employee Maintenance 窗體。
  4. 驗證無顯式引用即可調用模組,MEF 處理組件載入,實現完全解耦。

練習 2:動態擴充窗體

場景

擴充 EmployeeMaintenance 窗體,動態載入命令按鈕 (Add/Delete Employee)。應用程式無論有無擴充皆能正常工作,雙方鬆散耦合,透過 Interface 契約支援。

任務 1-2:標記按鈕為可導出

修改 AddEmployeeButton.cs 與 DeleteEmployeeButton.cs,加上 [Export(typeof(ICmdButtonInfo))]。

任務 3:添加 Panel 控制項

設計模式下拖放 Panel 至 DataGridView 下方,命名為 ButtonsPanel,寬度匹配 DataGridView。

任務 4:添加代碼載入擴充物件

  1. 在 EmployeeMaintenance 類頂部定義導入集合:
    [ImportMany]
    public Lazy<ICmdButtonInfo>[] ImportedButtons { get; set; }
  2. 實現 CreateButtons 方法遍歷集合,將按鈕加入 Panel,設置位置與 CompanyInfo。
  3. 在 EmployeeMaintenance_Load 調用 CreateButtons。
  4. 添加 empDataGridView_SelectionChanged 更新 CompanyInfo.SelectedEmployee,並在設計器綁定事件。
  5. 建置方案。

驗證

  1. 運行應用,選擇 Modules | Employees。
  2. EmployeeMaintenance 窗體出現兩新按鈕:Add Employee、Delete Employee。
  3. 測試新增/刪除列行功能。
  4. 在 Load 方法斷點觀察動態載入過程。

總結

本實驗使用 MEF 為應用程式添加擴充點並構建擴充插入。MEF 讓您以導出屬性載入外部組件、無需顯式引用、運行時動態擴充。您學習了 Import/Export 交互、透過介面契約指定導出組件。

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