MEF程序設計指南九:重組(Recomposition)MEF部件

  通過前篇八篇程序設計指南的學習,相信大家都知道應用程序部件的組合都是在初始化的時候進行裝配的。如果當應用程序已經初始化完成了,此時又有新的部件被導入且進行裝配,按照目前的實現方式就無法實現了,我們需要一種可以進行動態裝配、動態組合以及可以動態的進行新的部件被裝配組合的通知的功能,於此MEF所提供的重組(Recomposition)部件特性就可以派上用場了。

 

  這裏還是使用上一篇中應用的示例作爲功能演示場景,一個圖書接口其下有3個不同的具體實現類被定義在主程序中,詳細如下代碼段: 

namespace MEFTraining.Recomposition
{
    [Export(
typeof(IBookService))]
    
public class MEFBookService : IBookService
    {
        
public string GetBookName()
        {
            
return "《MEF程序設計指南》";
        }
    }

    [Export(
typeof(IBookService))]
    
public class ASPNETBookService : IBookService
    {
        
public string GetBookName()
        {
            
return "《ASP.NET項目案例》";
        }
    }

    [Export(
typeof(IBookService))]
    
public class SLBookService : IBookService
    {
        
public string GetBookName()
        {
            
return "《Silverlight高級編程》";
        }
    }
}

 

  那麼我們可以在需要使用到他們地方進行一個多項導入就可以導入所有的圖書實現類,詳細如下代碼。其中AllowRecomposition=true參數就表示運行在有新的部件被裝配成功後進行部件集的重組。

[ImportMany(AllowRecomposition = true)]
public IBookService[] Services { getset; }

 

  此時運行程序可以發現,Services的長度爲3,表示成功的將上面三種圖書的實現成功的裝配了。接下來我們在一個新的Silverlight應用裏面定義另外一個實現(OracleBookService),然後將此應用程序進行動態的加載並裝配,這裏MEF提供了DeploymentCatalog類,就是專門用來動態加載裝配外部Silverlight應用程序包的,只需要提供應用程序包所在的路徑就可以自動的完成下載和動態裝配,使用方式可參考下面代碼段,更詳細請查看《MEF程序設計指南七:使用目錄(Catalog)動態裝載xap與目錄篩選(Filtered Catalog)》一文中有詳細介紹。

var dc = new DeploymentCatalog("MEFTraining.Recomposition.Parts.xap");
dc.DownloadAsync();
dc.DownloadCompleted 
+= (rs, re) =>
{ };

 

  下面代碼段爲定義的第四個圖書實現部件,接下來將應用於重組功能演示示例。

namespace MEFTraining.Recomposition.Parts
{
    [Export(
typeof(IBookService))]
    
public partial class OracleBookService : UserControl,IBookService
    {
        
public OracleBookService()
        {
            InitializeComponent();
        }

        
public string GetBookName()
        {
            
return "《Oracle DBA手冊》";
        }
    }
}

 

  使用DeploymentCatalog去加載第四個一個部件所在的應用程序包,最終通過調試可以發現Services已經進行了重組,已經從原來的3個部件變爲了4個部件。

 this.DService.AddXap("MEFTraining.Recomposition.Parts.xap"null);

         

 

  在進行動態下載裝配的過程中,主程序或許需要準確的得到一個部件被裝配成功的通知,IPartImportsSatisfiedNotification接口就是一個當有新的部件進行裝配成功後的一個通知接口,可以準確的監聽到MEF容器的組合,一旦有新的插件部件進行導入裝載到MEF容器中,此接口就會自動的得到通知。其內部就一個接口方法,詳細如下代碼塊:

public void OnImportsSatisfied()
{
            
}

 

  下面爲完整的主程序代碼,本文完整示例代碼請下載代碼附件查看。

public partial class MainPage : UserControl, IPartImportsSatisfiedNotification
{
    [Import]
    
public IDeploymentService DService { getset; }

    [ImportMany(AllowRecomposition 
= true)]
    
public IBookService[] Services { getset; }

    
public MainPage()
    {
        InitializeComponent();
        CompositionInitializer.SatisfyImports(
this);
    }

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

    
public void OnImportsSatisfied()
    {
            
    }
}

 

  參考資料:Recomposition , DeploymentCatalog

  MEF官方網站:http://mef.codeplex.com/

  推薦指南:MEF程序設計指南一:在應用程序中宿主MEF

         MEF程序設計指南二:Silverlight中使用CompositionInitializer宿主MEF

         MEF程序設計指南三:MEF中組合部件(Composable Parts)與契約(Contracts)的基本應用

       MEF程序設計指南四:使用MEF聲明導出(Exports)與導入(Imports)

            MEF程序設計指南五:遲延(Lazy)加載導出部件(Export Part)與元數據(Metadata)

        MEF程序設計指南六:MEF中的目錄服務(DeploymentCatalog)

                   MEF程序設計指南七:使用目錄(Catalog)動態裝載xap與目錄篩選(Filtered Catalog)

        MEF程序設計指南八:部件生命週期(Parts Lifetime)託管

發佈了110 篇原創文章 · 獲贊 3 · 訪問量 32萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章