MEF程序設(shè)計(jì)指南九:重組(Recomposition)MEF部件
通過(guò)前篇八篇程序設(shè)計(jì)指南的學(xué)習(xí),相信大家都知道應(yīng)用程序部件的組合都是在初始化的時(shí)候進(jìn)行裝配的。如果當(dāng)應(yīng)用程序已經(jīng)初始化完成了,此時(shí)又有新的部件被導(dǎo)入且進(jìn)行裝配,按照目前的實(shí)現(xiàn)方式就無(wú)法實(shí)現(xiàn)了,我們需要一種可以進(jìn)行動(dòng)態(tài)裝配、動(dòng)態(tài)組合以及可以動(dòng)態(tài)的進(jìn)行新的部件被裝配組合的通知的功能,于此MEF所提供的重組(Recomposition)部件特性就可以派上用場(chǎng)了。
這里還是使用上一篇中應(yīng)用的示例作為功能演示場(chǎng)景,一個(gè)圖書接口其下有3個(gè)不同的具體實(shí)現(xiàn)類被定義在主程序中,詳細(xì)如下代碼段:
{
[Export(typeof(IBookService))]
public class MEFBookService : IBookService
{
public string GetBookName()
{
return "《MEF程序設(shè)計(jì)指南》";
}
}
[Export(typeof(IBookService))]
public class ASPNETBookService : IBookService
{
public string GetBookName()
{
return "《ASP.NET項(xiàng)目案例》";
}
}
[Export(typeof(IBookService))]
public class SLBookService : IBookService
{
public string GetBookName()
{
return "《Silverlight高級(jí)編程》";
}
}
}
那么我們可以在需要使用到他們地方進(jìn)行一個(gè)多項(xiàng)導(dǎo)入就可以導(dǎo)入所有的圖書實(shí)現(xiàn)類,詳細(xì)如下代碼。其中AllowRecomposition=true參數(shù)就表示運(yùn)行在有新的部件被裝配成功后進(jìn)行部件集的重組。
public IBookService[] Services { get; set; }
此時(shí)運(yùn)行程序可以發(fā)現(xiàn),Services的長(zhǎng)度為3,表示成功的將上面三種圖書的實(shí)現(xiàn)成功的裝配了。接下來(lái)我們?cè)谝粋€(gè)新的Silverlight應(yīng)用里面定義另外一個(gè)實(shí)現(xiàn)(OracleBookService),然后將此應(yīng)用程序進(jìn)行動(dòng)態(tài)的加載并裝配,這里MEF提供了DeploymentCatalog類,就是專門用來(lái)動(dòng)態(tài)加載裝配外部Silverlight應(yīng)用程序包的,只需要提供應(yīng)用程序包所在的路徑就可以自動(dòng)的完成下載和動(dòng)態(tài)裝配,使用方式可參考下面代碼段,更詳細(xì)請(qǐng)查看《MEF程序設(shè)計(jì)指南七:使用目錄(Catalog)動(dòng)態(tài)裝載xap與目錄篩選(Filtered Catalog)》一文中有詳細(xì)介紹。
dc.DownloadAsync();
dc.DownloadCompleted += (rs, re) =>
{ };
下面代碼段為定義的第四個(gè)圖書實(shí)現(xiàn)部件,接下來(lái)將應(yīng)用于重組功能演示示例。
{
[Export(typeof(IBookService))]
public partial class OracleBookService : UserControl,IBookService
{
public OracleBookService()
{
InitializeComponent();
}
public string GetBookName()
{
return "《Oracle DBA手冊(cè)》";
}
}
}
使用DeploymentCatalog去加載第四個(gè)一個(gè)部件所在的應(yīng)用程序包,最終通過(guò)調(diào)試可以發(fā)現(xiàn)Services已經(jīng)進(jìn)行了重組,已經(jīng)從原來(lái)的3個(gè)部件變?yōu)榱?個(gè)部件。
在進(jìn)行動(dòng)態(tài)下載裝配的過(guò)程中,主程序或許需要準(zhǔn)確的得到一個(gè)部件被裝配成功的通知,IPartImportsSatisfiedNotification接口就是一個(gè)當(dāng)有新的部件進(jìn)行裝配成功后的一個(gè)通知接口,可以準(zhǔn)確的監(jiān)聽(tīng)到MEF容器的組合,一旦有新的插件部件進(jìn)行導(dǎo)入裝載到MEF容器中,此接口就會(huì)自動(dòng)的得到通知。其內(nèi)部就一個(gè)接口方法,詳細(xì)如下代碼塊:
{
}
下面為完整的主程序代碼,本文完整示例代碼請(qǐng)下載代碼附件查看。
{
[Import]
public IDeploymentService DService { get; set; }
[ImportMany(AllowRecomposition = true)]
public IBookService[] Services { get; set; }
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官方網(wǎng)站:http://mef.codeplex.com/
推薦指南:MEF程序設(shè)計(jì)指南一:在應(yīng)用程序中宿主MEF
MEF程序設(shè)計(jì)指南二:Silverlight中使用CompositionInitializer宿主MEF
MEF程序設(shè)計(jì)指南三:MEF中組合部件(Composable Parts)與契約(Contracts)的基本應(yīng)用
MEF程序設(shè)計(jì)指南四:使用MEF聲明導(dǎo)出(Exports)與導(dǎo)入(Imports)
MEF程序設(shè)計(jì)指南五:遲延(Lazy)加載導(dǎo)出部件(Export Part)與元數(shù)據(jù)(Metadata)
MEF程序設(shè)計(jì)指南六:MEF中的目錄服務(wù)(DeploymentCatalog)
MEF程序設(shè)計(jì)指南七:使用目錄(Catalog)動(dòng)態(tài)裝載xap與目錄篩選(Filtered Catalog)
MEF程序設(shè)計(jì)指南八:部件生命周期(Parts Lifetime)托管
浙公網(wǎng)安備 33010602011771號(hào)