1. 程式人生 > >Prism V2之旅(5)

Prism V2之旅(5)

  上篇介紹了WPF的Attach Behavior(附加行為)模式以及如何在prism框架中如何使用附加行為和RegionAdapter的擴充套件.

這篇來介紹Prism中的很重要的一個功能模組化.

請下載Demo

基本概念

模組化的概念類似於現在網上比較流行的Widget,如下例子

google的個性化頁面

image

vista的sidebar

image

 

他們都有如下特性:

1.模組之間沒有關聯,模組之間不會相互引用

2.可插拔(可隨意增刪改模組)

使用prism框架,模組是基礎,一個系統是由多個模組組成,一個模組可以代表一個子功能,很重要的是這樣的做法可以降低開發的複雜度.下面我們來了解在prism中,模組的基本使用方法.

1.註冊模組

prism定義了一個IModule介面,Initialize方法是模組初始化的入口點,好比主程式的Main的入口點.

image

一般情況下,每新建一個模組都會新建一個專案來完成(當然這不是必須的規定).下面是一個簡單的例子

public class ModuleA : IModule
{
    private readonly IRegionManager regionManager;

    public ModuleA(IRegionManager regionManager)
    {
        this.regionManager = regionManager;
    }

    public void Initialize()
    {
        this.regionManager.Regions["MainRegion"].Add(new DefaultViewA());
    }
}

 

 

在模組初始化的時候,可以在依賴注入容器中獲取已註冊的服務

載入模組的方式有三種

  • 靜態載入模組
  • 根據目錄載入模組
  • 根據配置檔案載入模組

image

 

載入模組現在有以下概念:

  • 模組新增方法
  • 模組依賴性
  • 模組載入方式

2.載入模組之靜態載入模組

2.1重寫Bootstrapper的GetModuleCatalog方法

在Bootstrapper載入程式中重寫GetModuleCatalog方法,返回一個實現IModuleCatalog的物件,靜態載入模組請返回ModuleCatalog類

protected override IModuleCatalog GetModuleCatalog()
{
    ModuleCatalog catalog = new ModuleCatalog();
    catalog.AddModule(typeof (ModuleA), "ModuleD")
        .AddModule(typeof (ModuleB))
        .AddModule(typeof (ModuleD), "ModuleB")
        .AddModule(typeof (ModuleC), InitializationMode.OnDemand)
        ;
        
    return catalog;
}

 

2.2模組依賴(dependsOn)

AddModule方法,第一個引數是模組型別,第二個是該模組依賴的模組.如上ModuleA依賴於ModuleD,ModuleD依賴於ModuleB.所以上面的載入順序如下.模組依賴在不同載入模組的方式都有,只不過做法不同而已

image

2.3載入方式(初始化載入和按需載入)

(1)初始化載入

InitializationMode決定模組是否初始化時載入,預設是WhenAvailable,OnDemand則會在請求時載入

public enum InitializationMode
{
    /// <summary>
    /// The module will be initialized when it is available on application start-up.
    /// </summary>
    WhenAvailable,

    /// <summary>
    /// The module will be initialized when requested, and not automatically on application start-up.
    /// </summary>
    OnDemand
}

 

以上配置,將會初始化ModuleA,B,C三個模組,ModuleC則不初始化.

(2)按需載入

按需載入可以減少初始化時載入模組的時間.可以在需要時使用IModuleManager介面的LoadModule方法來載入所需模組

(注意:這裡雖是延遲載入,但這個模組已經進來,就是說這個模組的dll還是被載入了,只不過沒初始化而已)

public DefaultViewB(IModuleManager moduleManager)
    : this()
{
    this.moduleManager = moduleManager;
}

private void OnLoadModuleCClick(object sender, RoutedEventArgs e)
{
    // This logic is placed in code-behind instead of a presenter
    // for the ease of demonstrating module loading.
    this.moduleManager.LoadModule("ModuleC");
}

 

 

3.載入模組之根據目錄載入模組

三個步驟

3.1.把需要的模組放在某個目錄下面

3.2.用Attribute配置相關模組

[Module(ModuleName = "ModuleA")]
[ModuleDependency("ModuleD")]
public class ModuleA : IModule
{
    private readonly IRegionManager _regionManager;

    public ModuleA(IRegionManager regionManager)
    {
        _regionManager = regionManager;
    }

    public void Initialize()
    {
        _regionManager.Regions["MainRegion"].Add(new DefaultViewA());
    }
}

 

3.3.重寫Bootstrapper的GetModuleCatalog方法返回DirectoryModuleCatalog,並指定模組目錄.

protected override IModuleCatalog GetModuleCatalog()
{
    return new DirectoryModuleCatalog() {ModulePath = @".\Modules"};
}

 

3.載入模組之根據配置檔案載入模組

兩個步驟

3.1.配置檔案

<modules>
  <module assemblyFile="Modules/ModuleD.dll" moduleType="ModuleD.ModuleD, ModuleD" moduleName="ModuleD">
    <dependencies>
      <dependency moduleName="ModuleB"/>
    </dependencies>
  </module>
  <module assemblyFile="Modules/ModuleB.dll" moduleType="ModuleB.ModuleB, ModuleB" moduleName="ModuleB"/>
  <module assemblyFile="Modules/ModuleA.dll" moduleType="ModuleA.ModuleA, ModuleA" moduleName="ModuleA">
    <dependencies>
      <dependency moduleName="ModuleD"/>
    </dependencies>
  </module>
  <module assemblyFile="Modules/ModuleC.dll" moduleType="ModuleC.ModuleC, ModuleC" moduleName="ModuleC" startupLoaded="false"/>
</modules>

 

3.2.重寫Bootstrapper的GetModuleCatalog方法返回ConfigurationModuleCatalog

(注意startupLoaded屬性如果設定為false,則該模組的dll不會載入,這有區別與靜態載入的方式,這樣的做法可以真正做到按需載入)

好,這篇就寫到這裡.Demo是prism內建的.