Prism V2之旅(5)
上篇介紹了WPF的Attach Behavior(附加行為)模式以及如何在prism框架中如何使用附加行為和RegionAdapter的擴充套件.
這篇來介紹Prism中的很重要的一個功能模組化.
基本概念
模組化的概念類似於現在網上比較流行的Widget,如下例子
google的個性化頁面
vista的sidebar
他們都有如下特性:
1.模組之間沒有關聯,模組之間不會相互引用
2.可插拔(可隨意增刪改模組)
使用prism框架,模組是基礎,一個系統是由多個模組組成,一個模組可以代表一個子功能,很重要的是這樣的做法可以降低開發的複雜度.下面我們來了解在prism中,模組的基本使用方法.
1.註冊模組
prism定義了一個IModule介面,Initialize方法是模組初始化的入口點,好比主程式的Main的入口點.
一般情況下,每新建一個模組都會新建一個專案來完成(當然這不是必須的規定).下面是一個簡單的例子
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()); } }
在模組初始化的時候,可以在依賴注入容器中獲取已註冊的服務
載入模組的方式有三種
- 靜態載入模組
- 根據目錄載入模組
- 根據配置檔案載入模組
載入模組現在有以下概念:
- 模組新增方法
- 模組依賴性
- 模組載入方式
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.所以上面的載入順序如下.模組依賴在不同載入模組的方式都有,只不過做法不同而已
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內建的.