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

MEF 程式設計指南(七):動態載入 XAP 與目錄篩選實戰

     編輯:關於.NET

若不使用 MEF 托管擴充,動態下載與解析 .xap 套件需自行使用 WebClient。MEF 底層同樣採用 WebClient,再透過 AggregateCatalog 動態組合部件(原始碼可參考 DeploymentCatalog.cs)。

封裝 XAP 動態載入服務

上一篇已介紹目錄服務介面封裝,此處專注於動態載入 .xap 的 AddXap 方法:

public void AddXap(string relativeUri, Action<AsyncCompletedEventArgs> completedAction)
{
    DeploymentCatalog catalog;
    if (!_catalogs.TryGetValue(relativeUri, out catalog))
    {
        catalog = new DeploymentCatalog(relativeUri);
        catalog.DownloadCompleted += (s, e) => completedAction?.Invoke(e) ?? DownloadCompleted(e);
        catalog.DownloadAsync();
        _catalogs[relativeUri] = catalog;
        _aggregateCatalog.Catalogs.Add(catalog);
    }
}

使用時僅需導入介面並呼叫:

[Import]
public IDeploymentService Service { get; set; }

private void button1_Click(object sender, RoutedEventArgs e)
{
    this.Service.AddXap("MEFTraining.MefCatalogs.Parts.xap", null);
}

IPartImportsSatisfiedNotification:部件裝配完成通知

當新部件成功組合進容器,實作此介面的類別會自動收到 OnImportsSatisfied() 回呼,適合用於初始化後續邏輯。

FilteredCatalog:目錄篩選的核心實作

當只需目錄中特定部件時,可使用 ComposablePartCatalog 與 INotifyComposablePartCatalogChanged 建立篩選目錄:

public class FilteredCatalog : ComposablePartCatalog, INotifyComposablePartCatalogChanged
{
    private readonly ComposablePartCatalog _inner;
    private readonly INotifyComposablePartCatalogChanged _innerNotifyChange;
    private readonly IQueryable<ComposablePartDefinition> _partsQuery;

    public FilteredCatalog(ComposablePartCatalog inner,
        Expression<Func<ComposablePartDefinition, bool>> expression)
    {
        _inner = inner;
        _innerNotifyChange = inner as INotifyComposablePartCatalogChanged;
        _partsQuery = inner.Parts.Where(expression);
    }

    // Changed / Changing 事件轉發給內部目錄
    public override IQueryable<ComposablePartDefinition> Parts => _partsQuery;
}

中繼資料驅動的部件篩選

使用 [PartMetadata] 標記部件,再以 Lambda 運算式篩選:

[PartMetadata("UC", "AA")]
[Export(typeof(UserControl))]
public partial class AA : UserControl { ... }

[PartMetadata("UC", "BB")]
[Export(typeof(UserControl))]
public partial class BB : UserControl { ... }

[PartMetadata("UC", "CC")]
[Export(typeof(UserControl))]
public partial class CC : UserControl { ... }

篩選程式碼:

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 perRequest = new CompositionContainer(filteredCat, parent);
var control = perRequest.GetExportedValue<UserControl>(); // 取得 CC

此機制讓大型模組化應用能依中繼資料動態決定載入哪些部件,極大提升彈性。

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