Composite UI Application Block (CAB) 詳解

微軟開發了一套開源的企業庫 (Enterprise Library),通過使用這套企業庫裏面提供的各種應用程序塊可以極大的提高應用程序的開發效率和縮短開發週期,也由此得到了大家的廣泛應用。
企業庫包括大家熟知的如下應用程序塊:

  • Caching Application Block.
  • Cryptography Application Block. 
  • Data Access Application Block.
  • Exception Handling Application Block.
  • Logging Application Block.
  • Security Application Block.
  • Validation Application Block.
  • Policy Injection Application Block.

這些應用程序塊都是一些常用的非業務相關的公共模塊,相關資料在網上搜一下就一大堆,所以很多使用過企業庫的朋友應該並不陌生。所以這裏也就不再多說。
       我今天要給大家介紹的其實也是一個應用程序塊,但是是獨立於企業庫單獨安裝的。網上也能搜到一些相關資料,但總覺不夠全面,如果不看安裝程序提供的幫助文檔,網上查到的很多中文文章,還真讓人看的一知半解。知其然,不知其所以然,所以本人就乾脆看着幫助文檔來細細研究。先給個下載地址:http://www.microsoft.com/downloads/details.aspx?FamilyId=7B9BA1A7-DD6D-4144-8AC6-DF88223AEE19&displaylang=en
下載後會有一個CAB_CS的安裝文件,安裝即可。
       按照微軟官方的說法,Composite UI Application Block (CAB,混合UI應用程序塊)使用了目前商業客戶端應用程序常用的設計模式來構建了一個靈活的基礎框架。基於這個框架可以很容易的幫助你編寫運行在microsoft .net平臺上的具有複雜用戶交互界面的Windows Form 應用程序。那麼他有哪些優點呢?


1:允許構建由各個具有協作關係的獨立模塊組合成的複雜應用
2:分離關注點,能將各個模塊的開發的關注點和Shell的開發分離開來
3:提供了一個能支持高質量的桌面應用開發的框架
4:提高了生產力和節約了開發時間,進一步鞏固了架構師和開發人員的勞動成果。

首先我們來看看Composite UI Application Block中涉及的相關概念和術語。這裏會做一個簡單的介紹,後續文章會詳細說到其用法。

應用程序架構元素

CAB. Composite UI Application Block的縮寫

Module應用程序的組成部件,其中包含SmartParts,支持Service,業務邏輯和配置信息等

ObjectBuilder.通過策略和配置信息自動創建對象實例的對象構造器

Shell. 承載了用戶接口元素,SmartPart,服務的外殼宿主程序

Visualizer. CAB中提供的,可以查看應用程序中的WorkItem的動態分級視圖的工具。

外殼元素

shell application. 承載了用戶接口元素,SmartPart,服務的外殼宿主程序。

SmartPart. 一個展現數據的視圖,比如控件,Windows 窗體或是一個嚮導頁。

SmartPartInfo. 存放SmartPart的相關信息的類,以便被workspace所使用,比如可以在Smartpartinfo中設置SmartPart的顯示標題。

UIElement. 一個以Shell作爲宿主的控件,該控件能被多個Module所共享,這樣的控件有:toolbar button , menuitem , status panel等

UIElement adapter. 管理特殊類型的UIElement的顯示的類

Workspace封裝了控件和SmartParts的某種可視化的佈局的組件,比如以Tab方式顯示頁面。

相關模式

Blackboard. 通過提供一個共享信息的地方,使其他組件能設置或獲取這個地方的信息,已達到信息共享的模式。

Builder/Inversion of Control/Dependency Injection. 該模式通過組件之間的依賴關係進行運行時的注入,來達到組件重用和鬆散耦合的目的。

Event Broker. 允許鬆散耦合的組件通過發佈訂閱的方式進行通訊的模式。

Memento.持久化一個對象的內部狀態狀態,並在需要的時候可以在後期對狀態進行恢復的模式。

Model-View-Controller (MVC). 該模式將領域模型,視圖和基於用戶輸入產生的行爲(控制器)分成3個不同的組成部分。視圖部分提供給用戶進行交互,交互信息通過視圖傳到控制器,控制器更新模型,模型引發事件,從而更新視圖。關係圖如下:

Model-View-Presenter (MVP). 該模式將領域模型,視圖和基於用戶輸入產生的行爲(控制器)分成3個不同的組成部分。視圖部分提供給用戶進行交互,交互信息通過視圖傳到控制器,控制器更新模型,模式觸發事件到控制器,同時,控制器負責更新視圖。關係圖如下:

相關編程模型

Component. 應用程序的可視或非可視組成部件,比如SmartParts, services, 和控件.

Container. 包含了組件或服務的類。

event broker. 支持鬆散耦合的發佈訂閱事件機制的系統。

State. 存在於WorkItem中,以鍵-值的字典的方式來存放共享信息。

Service.以鬆散耦合的方式爲其他的組件提供功能的組件。比如:ModuleLoaderService

WorkItem運行時的組件和服務的容器該容器能協作其中封裝的用例代碼的執行。一般WorkItem和用例對應。

相關角色

infrastructure developer. 負責進行應用程序的基礎服務的開發的開發人員。

module developer. 負責進行應用程序的業務組件的開發的開發人員。

shell developer. 負責建立應用程序外殼的開發人員。

SmartPart developer. 負責開發應用程序的SmartParts的開發人員。

CAB提供了一個非常靈活的編程框架,利用這一框架,可以很好的將一個應用分離成不同的模塊進行開發。
    我們來看看一個基於CAB的典型應用都有哪幾部分組成: 

首先一個CAB應用需要通過繼承自FormShellApplication的應用程序類來進行啓動。FormShellApplication需要傳入兩個類型參數,繼承自WorkItem的類,和繼承自Form的類(應用程序主界面FormShell)。主界面上可以放置供所有界面視圖使用的公共的UI Element (如:Toolbar)。和顯示用戶界面的WorkSpace。WorkItem是封裝了用例實現的容器,容器中的對象可以共享信息。WorkItem也可以包含下級WorkItem.

由於CAB的優點之一是能夠很好的支持模塊化開發,業務開發人員可以專注於某一方面業務模塊的開發,如:倉庫管理系統中,入庫和出庫就是同一個系統中的兩個業務點,在CAB的支持下,完全可以將這兩個業務點交由不同的開發人員進行開發,只要按照同樣的既定的規範開發(界面規範,接口規範等),就能很好地進行集成。CAB中通過Module很好的實現了這一點。

一般我們將module實現於dll文件中,每個Dll文件可能包含系統某一方面的功能,當我們在獨立開發好各個Module之後,我們可以利用CAB有選擇的加載這些功能模塊,從而支持系統運行。要實現Module被加載很簡單,只需要在ProfileCatalog.xml中將需要被加載的module配置進去就可以了。當然前提是被加載的模塊需要符合CAB的Module設計的標準。如圖中所示,這個dll中需要有一個繼承自ModuleInit的類,Module被加載的時候,該類的Load方法將被調用,所以大家也可以在繼承類中通過重載Load方法來擴展其加載時的行爲。

一般情況下,在獨立的模塊中,我們還需要實現相應的繼承WorkItem的類來實現其業務用例的封裝,這個WorkItem我們需要將其添加到RootWorkItem的WorkItems集合中,以便和其建立聯繫。

在WorkItem中可以使用MVP的模式來實現我們的系統。上圖中的View是在主窗體的WorkSpace中顯示的和用戶進行交互的界面Presenter(主持人)則是響應界面操作,處理業務邏輯的地方(類似於controller)Model則是我們的數據

雖然我們的系統可以模塊化的獨立開發,各個模塊之間實現了鬆耦合,但是系統運行時,CAB還是需要通過某種方式將各個模塊糅合在一起,以便形成一個有機的整體。首先CAB是一個IOC的容器,它可以在運行時根據需要實例化各種對象,並將其注入到對其有需要的對象中,達到對象的組裝,然後可以通過發佈訂閱事件系統及共享State實現了對象間的通訊。

CAB涉及的Dll有:
    
    常用的命名空間如下:
    
    附兩張CAB中命名空間Microsoft.Practices.CompositeUI和Microsoft.Practices.CompositeUI.Winforms涉及的類和接口:
       
    

個人認爲,CAB是的不錯的WinForm應用框架,目前主要還是體現在對界面層和業務邏輯層的支持上。如果配合其他的技術框架如Nhibernate對數據庫層進行支持,將會更好。

現在我們來看看基於CAB的應用程序中非常重要的一個類。這個類可以認爲是一個CAB應用的啓動點。他就是FormShellApplication

FormShellApplication的繼承關係如下:


該類需要傳入兩個類型參數,一個是繼承自WorkItem的類(如果不需要通過重載WorkItem的OnRunStarted方法來實現更多處理,這裏可以直接使用WorkItem),一個是繼承自Form的窗體。

public class Program:FormShellApplication<MyWorkItem,ShellForm>

通常我們在Main方法中調用其Run方法,執行Run方法會初始化許多應用程序信息。可以通過override來重寫或增加FormShellApplication的方法處理。

FormShellApplication的初始化包括(可以通過子類重載FormShellApplication的相關方法來判斷其執行順序)以下步驟:

1. RegisterUnhandledExceptionHandler

2. 創建 Build strategies

3. 創建頂級 WorkItem

4. 創建和初始化 Visualizer

5. 添加 services

6.創建Shell

CAB提供的標準服務如下,開發人員可以在此基礎上進行擴展:

  • SimpleWorkItemActivationService
  • FileCatalogModuleEnumerator
  • WindowsPrincipalAuthenticationService
  • ModuleLoaderService
  • DataProtectionCryptographyService
  • TraceSourceCatalogService
  • CommandAdapterMapService
  • WorkItemExtensionService
  • WorkItemTypeCatalogService
  • ControlActivationService

執行了FormShellApplication的子類的Run方法,一個CAB應用程序就算是啓動了。隨後就是根據自己的需要來執行WorkItem了。

通過前面的介紹我們可以知道在靜態Main方法中執行繼承自FormShellApplication的對象實例可以進行很多框架的初始化工作,如加載模塊,加載服務等。從FormShellApplication的類型定義中:

public abstract class FormShellApplication<TWorkItem,TShell> : WindowsFormsApplication<TWorkItem,TShell> where TWorkItem : WorkItem where TShell : Form

可以看到,需要兩個類型參數,一個是WorkItem,一個是Form,FormShellApplication在進行初始化工作的時候會對這兩個類型進行實例化。並且會將Form類型的實例 Show出來。這裏的Form類型的實例即是我們應用程序的主界面。

主界面將是用戶與系統的主要交互區域。他將做爲一個容器,承載其他的業務界面。

CAB中提供了WorkSpace組件,他作爲用戶控件和SmartPart控件的顯示容器,可以以各種各樣的統一的顯示方式呈現業務界面。也就是說WorkSpace可以以不同的風格呈現其中的用戶控件。WorkSpace支持顯示,隱藏,激活和關閉其中的用戶控件。當然,CAB目前提供了幾種默認的顯示風格,接下來我們將一個一個介紹,如果開發人員覺得這些顯示風格還不夠用,當然也可以自己進行擴展。

所有類型的WorkSpace都是實現了接口IWorkSpace的。

目前CAB提供的WorkSpace有:

WindowWorkspace

MdiWorkspace

TabWorkspace

DeckWorkspace

ZoneWorkspace

下面就來說說每種WorkSpace的特點:

1, WindowWorkSpace

該WorkSpace能將你需要在其中顯示的用戶控件在一個WinForm中顯示出來,我們可以通過和該WorkSpace對應的WindowSmartPartInfo來設置用戶控件的顯示屬性,如標題信息,是否是模式窗口等。


2, MdiWorkspace

該WorkSpace是在WindowWorkSpace的基礎上發展而來的,他同樣將一個用戶控件在單獨的Form中進行顯示,並且,他還將以MDI的形式顯示和管理其子窗體。對應用戶控件的顯示信息的設置是通過設置smartPartInfo,然後作爲參數傳入WorkSpace的Show方法。

3, TabWorkspace

該WorkSpace能將你需要在其中顯示的用戶控件以Tab頁的形式顯示出來,我們可以通過和該WorkSpace對應的TabSmartPartInfo來設置用戶控件的顯示屬性,如標題信息。

4, DeckWorkspace

該WorkSpace將以類似於重疊的卡片的形式來顯示用戶控件,當前激活的界面將在卡片的最上方。卡片的數序是由Workspace進行管理。沒有和該WorkSpace對應的SmartPartinfo.

5, ZoneWorkspace

該WorkSpace將以平鋪的方式顯示用戶控件,比如類似OutLook的界面,可以將一個界面劃分成多個Zone,每個Zone都是作爲呈現用戶控件的一個容器。同樣的,我們可以通過設置ZoneSmartPartInfo來設置用戶控件在WorkSpace中的顯示屬性。

前面已經說到,CAB框架中除了提供了強大的支持功能,如依賴注入,事件機制,界面組合顯示…,還有一個專門封裝業務邏輯的WorkItem。企業應用系統其實主要就是企業業務的自動化實現,一個應用框架提供的支持功能都只是爲了更好地爲業務服務。下面就來看看CAB中的WorkItem是如何封裝業務用例的。

首先看看WorkItem都包含哪些元素?

從WorkItem的屬性列表中我們可以看出,WorkItem中支持命令和事件,同時WorkItem可以嵌套,通過Parent進行關聯,通過RootWorkItem可以獲取頂層WorkItem,開發人員可以利用這一特性來組織自己業務用例和劃分業務用例的粒度。WorkItem中使用State來共享信息,在同一個WorkItem容器中的對象可以共享訪問這個信息。 WorkItem容器中的對象對其中的Service都可以訪問。

WorkItem通過調用Run方法進行啓動,調用這個方法的時候會調用他的OnRunStarted方法,一般我們自定義了一個WorkItem,如果有需要可以重載其OnRunStarted方法來自定義其啓動邏輯。Run方法調用後會觸發RunStarted事件。

一般我們會藉助WorkItem提供的特性,採用MVC的模式進行業務用例的封裝。使用SmartPart作爲用戶交互的UI顯示部分(View),創建一個控制類來進行業務邏輯的封裝(Controller),然後將業務數據存放於內存實體中(Model)。用戶界面和內存實體採用綁定的方式關聯起來。

這就是典型的MVC模式的應用,我們來看看他的初始化和用戶交互過程中的操作是如何進行的?

初始化:

 

    1,應用系統加載WorkItem,WorkItem將用戶界面在WorkSpace中進行顯示
    2,用戶界面加載,調用控制邏輯進行初始數據的處理和獲取
    3,控制邏輯獲取初始數據
    4,控制邏輯將數據存放於內存實體中
    5,控制邏輯將數據與用戶界面進行綁定,界面會自動根據綁定的數據源進行初始化顯示

用戶交互:
 

 

 

1,用戶操作用戶界面,調用相應控制邏輯
      2,控制邏輯進行業務處理,進行相關服務或數據庫訪問
      3,控制邏輯修改內存實體中的數據
      4,由於數據與界面綁定,數據的變化直接反應到界面顯示。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章