NetBpm 組織架構(4)

大牛的傑做,贊一個html

轉自:NetBPM工做流的架構設計及實現淺析web

 

讀前的話:因爲本文涉及內容頗多,如有地方讀來不很明白,建議先跳過,總體上有個認識後,再回過頭來理解。做者認識有限,如有錯誤,歡迎斧正:)原文地址: NetBPM工做流的架構設計及實現淺析(轉載請保留)數據庫

NetBPM組件接口

    NetBPM由一系列的組件構成,每個組件都實現一個核心接口(採用Facade Pattern)。不一樣組件各自負責的核心功能根據WfMC規範而來。
    NetBPM接口圖:apache

 
  1. 爲流程開發者提供的接口(Process Developer):該接口負責加載流程定義到NetBpm引擎。首先,流程開發者依照nPdl建立一個流程定義,並將其打包成流程定義壓縮包(該包包含一個業務流程的全部信息),而後經過NetBPM Web界面或者是其餘方式把流程定義壓縮包加載到NetBPM引擎,在加載過程當中流程定義壓縮包將會被解析被保存到NetBPM數據庫中。
  2. 爲用戶提供的接口(User):這裏用戶表示執行流程的人。流程運行主要有2種行爲:開始一個流程和執行一個活動(activity)。開始一個流程將建立該流程的一個流程實例,一個流程實例對應流程定義的一次執行。一個流程實例包含了一個或多個並行的flow-of-execution(見flow)。對於處在activity-state(活動節點,見nPdl)的flow,系統必定會指派一個具體的人(或者組)或者第三方來執行活動(activity)。執行活動是Execution Interface的第二種行爲。固然了,運轉接口還會實現一些其餘的方法如獲取任務列表,獲取有效流程定義列表等。  
  3. 外部IT系統(External IT Systems)和NetBpm引擎之間的接口:外部IT系統能以2種方式實現和NetBPM的交互。
    •  系統發起交互:系統直接和外部IT系統交互。當系統想要觸發流程中的某一個action時,它必須使用上面提到的Execution Interface。
    •  流程發起交互:對於流程發起交互這種類型來講,須要有Interactors。這些Interactors是流程定義的一部分,它包含在流程定義包內(實際上Interactors就是可以訪問FlowContext的.NET程序集,也就是咱們後面要說到的包含委託類的程序集合)。Interactors在FlowContext(FLOW運行上下文環境)和外部IT系統之間創建起了通訊渠道。
  4. 組織架構數據(Organisational Datastore)和NetBpm之間的接口:仔細想一想,NetBpm是否是還缺了點什麼,沒錯,那就是組織架構的信息:好比說人、團隊、部門、角色等。由於在現實狀況中,對於不一樣的組織結構,組織架構信息可能被保存在不一樣類型的數據庫中,如LDAP系統,關係型數據庫等。爲了讓NetBPM可以在一個現實的組織架構中實現快速部署,NetBPM把全部的組織架構信息都彙集在一個組件(Organisation Component)中。這種作法也就是咱們一般說道會話門面模式(Session Façade Pattern),它使得NetBPM訪問來自不一樣數據源的組織架構信息變得更爲簡單。

     下面咱們逐步介紹NetBPM的各個組件,下面是NetBpm組件結構圖:編程

 

定義組件(Definition Component)

     該組件實現核心接口IDefinitionSessionLocal,用來解析、加載流程定義壓縮包,並將其保存到數據庫中。此外,它還提供獲取某個流程定義,獲取全部有效流程定義列表等和流程定義相關的方法。架構

運轉組件(Execution Component)

     該組件實現了核心接口IExecutionSessionLocal,它是NetBPM引擎推進核心,如前面如述,它主要實現2個方法:開始一個流程實例(Start ProcessInstance)和執行一個活動(Perform Activity)。另外,它還提供獲取用戶任務列表,取消流程實例等輔助流程運轉的方法。框架

組織架構組件(Organization Component)

     該組件實現接口IOrganisationSessionLocal,它把全部的組織架構信息都彙集在一塊兒,包括Users、Groups和Memberships。運轉組件在爲activitie-state指定執行者時,須要有關user和group的信息。這些信息將以只讀模式由組織架構組件向運轉組件提供。下面是NetBPM默認的組織架構組織數據模型。在此基礎上,咱們能夠很方便的實現自定義的適合實際項目需求的組織架構組件,以和咱們的用戶數據庫或者是LDAP系統相關聯。ide

     NOTE:NetBPM源碼中實現的只是一個簡單的組織架構模型,但它提供了一種思考方向,咱們能夠很方便在此基礎上進行擴展來實現知足切實需求的自定義組織架構組件:)工具

日誌組件(Log Component)

     該組件實現接口ILogSessionLocal,用來記錄工做流引擎的操做痕跡,象屬性值的更新(如用戶提交的表單被上級打回從新填寫,那麼就會出現屢次表單數據,這就是一種屬性更新),委託類的調用狀況等都會被記錄下來保存到數據庫中。單元測試

任務調度組件(scheduler component)

     該組件實現接口ISchedulerSessionLocal,在現實的業務流程中,咱們常常會遇到須要定時觸發某個任務的需求,任務調度組件正是做用於此。引擎或者是第三方把須要在某個時刻執行的任務信息(包括任務執行環境、執行時間等)封裝成Job保存到數據庫中。任務調度組件將按照指定的時間間隔不停的掃描任務表,根據執行時間對比來執行定時到了的Job。

管理監控組件(Admin Component)

     該組件用來對流程定義,流程實例執行狀況等進行監控。(源碼待完善)下面是NetBpm核心項目在Visual 該組件用來對流程定義,流程實例執行狀況等進行監控。(源碼待完善)

 下面是NetBPM核心項目在Visual Studio解決方案中的源碼結構圖,全部組件都包含在Workflow文件夾下,每個文件夾分別對應實現了一個核心組件。
 

 

NetBpm中的幾個重要概念

flow

     flow不知道翻譯爲何好,在JBPM中叫作Token,翻譯爲令牌,這裏咱們就叫作flow吧。它表明activity-states(活動節點,見nPdl)的一個「thread of execution」,至關因而一次流程實例執行過程當中在流程定義模板中的令牌(還真難描述清楚,看下面一塊兒理解:))。前面說了,一個流程實例表明一個流程定義的一次執行。以下圖所示,流程實例的狀態能夠當作是一顆flows樹。 

      當開始一個流程實例後,在start-state(開始節點,見nPdl,start-state實際上能夠看作是一種特殊的activity-state)引擎將自動產生一個名爲root的flow。flow中包含了該流程實例的相關信息,如屬性值、流程定義信息、flow所在activity-state的執行者等。root flow在遇到fork(分散節點,見nPdl)以前,將更新其帶有的實時信息(如執行者、屬性值等),這些實時信息隨着流程的運轉而變化。遇到fork後,根據ForkHandler委託類,root flow將分散成若干(>1個)forked flow(咱們能夠把root flow稱爲這些forked flow的父flow)。如果分散爲多個,則此時forked flow將並行運行,父flow則暫時退隱,只至到join(匯聚節點,見nPdl)匯聚,引擎將根據join定義的JoinHandler委託類來肯定激活父flow的機制。

     NOTE:關於fork和join機制,請參考nPdl fork、join小節一塊兒理解。

attributes(屬性)

     attribute用來表示流程實例中的變量。一個attribute-instance(屬性實例,也就是屬性值)表明一次流程實例執行過程當中對應屬性的實例。屬性通常有幾種,一種是activity-state(包括start-state)須要用戶或者第三方來填寫(更新)的屬性(通常對應用戶Web界面表單上要填寫的值),一種是角色對應的屬性,還有一些用做標識屬性(用來存儲某些信息以方便後面的節點運用這些信息處理邏輯判斷)。

  1. serializer(屬性的序列化): 

    Serializer和HtmlFormatter都是委託類,Serializer負責把屬性實例在.NET-Objects和文本兩種狀態間進行轉換,以方便把屬性值存入和取出數據庫。而Htmlformatter主要用來聯繫屬性值和Web Forms顯示時對應的http-text。
  2. attribute的範圍:attribute-instances(屬性實例)和flow有關。在process-definition(流程定義根節點,見nPdl)節點中定義的attribute和root-flow關聯,而在concurrnet-block(並行運行塊,見nPdl)中定義的局部attribute實例則和forked flow關聯。一個flow可以「看見」和它關聯的全部屬性以及該flow的父flow的全部屬性。

引擎運行時上下文環境(Execution Context)

     

由於圖片太大,關於繼承IHandlerContext的接口關係圖查看點擊這裏

     ExecutionContext(ExecutionContextImpl類型的對象,咱們暫且翻譯爲運行時上下文環境:)) 包含了引擎在運行時和流程實例相關的全部有用信息(上文中提到的flowcontext就是一種ExecutionContext),它在委託類(包括流程定義壓縮包中程序集中定義的委託類)和流程引擎之間創建起了相互聯繫的渠道,這是很是關鍵的。如上面ExectutionContext 類圖所示,ExecutionContextImpl實現了下面這些接口:IAssignmentContext、IDecisionContext、IForkContext、IActionContext、IJoinContext、IProcessInvocationContext、ITaskContext,這些接口都是爲匹配特定的委託類而設計,它們規範了一種特定的上下文環境,如IActionContext匹配action類型委託類,IDecisionContext匹配DecisionHandler類型委託類等,而ExectutionContext是全部這些特殊的運行時上下文環境的一個綜合。當引擎在運轉組件把ExectutionContext做爲參數傳送到具體類型的委託類時(關鍵:這就是委託類和流程引擎創建聯繫的方式),ExecutionContext對象將「拆箱」成爲特殊的Context,如:把ExecutionContext對象傳給action類型的委託類Run()方法時,ExecutionContext對象將拆箱爲ActionContext對象以限制其可以調用的方法。

     如「繼承自IHandlerContext的接口」圖中所示,這些接口都繼承了同一個接口IHandlerContext。IHandlerContext是一個規範了最基本的委託類處理上下文環境的接口,實現該接口的繼承幾口也就都要實現IHandlerContext中定義的方法,固然每一種繼承它的特定接口又均可以具備其特定的方法。咱們先看公共接口IHanlderContext類圖:如上IHandlerContext接口圖所示,這些接口都繼承了同一個接口IHandlerContext。IHandlerContext是一個規範了最基本的委託類處理上下文環境的接口,實現該接口繼承接口的類也就都實現了IHandlerContext中定義的方法。固然,每一種繼承它的特定接口又均可以具備其特定的方法。咱們先看公共接口IHanlderContext類圖:

     大多數的方法,咱們從方法名稱就能夠看出其具體做用了,這裏重點介紹下GetAttribute()方法和GetConfiguration()方法,這是咱們在寫委託類實現時,要常常用到的2個方法。GetAttribute()用來獲取流程實例中的屬性值,包括流程前面處理者產生的屬性值(如用戶填寫表單的值)和前面處理引擎事件中設置的表示屬性值(注:IActionHandler具備SetAttribute()方法,該方法常常用來標識屬性值,供後面程序邏輯用)等。而GetConfiguration()用來獲取流程定義中設置的parameter(參數,請nPdlparameter小節)。

     下面再來看幾種典型的特定上下文環境接口:

  • IAssignmentContext:爲IAssignmentHandler委託類提供引擎上下文環境,該接口定義了獲取組織架構信息的方法,具體實現方法見類圖。
  • IActionContext:爲action提供引擎上下文環境,注意其具備SetAttribute的方法,能夠爲流程實例中的屬性賦值,具體實現方法見類圖。
  • IForkContext:爲IForkHandler委託類提供引擎上下文環境,它定義瞭如何從父flow分散forked flow的方法,見類圖。
  • IJoinContext:爲IJoinHandler委託類提供引擎上下文環境,它定義了獲取其餘並行flows的方法,見類圖。
  • IProcessInvocationContext: 爲IProcessInvocationHandler委託提供引擎上下文環境,實現方法見類圖。
  • 其餘的委託類型上下文環境除了實現基本IHandlerContext方法外,沒有特定的方法,請參考IHandlerContext方法。

委託類

     在前面咱們一直提到委託類,那麼委託類究竟是什麼呢?這裏委託的概念指的不是.NET Framework中delegate,這裏能夠理解它爲「委託、代爲處理」這樣的概念就好。

     NetBPM被設計成通用的流程處理引擎,NetBPM核心執行引擎只負責處理最基本的業務流程邏輯,全部不定的邏輯都被委託給一系列的接口,這些接口稱做Delegation Interfaces(委託接口),而實現這些接口的類就是委託類。流程定義約定在什麼場合使用什麼委託類型,引擎和委託類如何關聯也在流程定義中完成。

    爲了達到最大的可擴展性,流程開發者在流程定義時能夠選擇下面任意一種委託類實現方式:

  1. 使用已經在NetBpm引擎中實現的有效的委託類。(具備通用性的委託建議採用這種方式在引擎中定義,以便重用)
  2. 使用自定義的委託類,以.NET程序集的形式經過流程定義壓縮包動態加載。

     正是方式2這種形式給NetBPM帶來了極大的靈活性,把只適合於某個特定流程的的程序邏輯(這些每每佔了大多數)以.NET程序集的形式定義在流程定義壓縮包中,NetBpm經過流程定義組件將其解析並保存至數據庫。當引擎運轉流程須要調用委託類時,引擎利用反射技術實例化出委託類對象,而後利用上文介紹的運行時上下時環境(ExecutionContext)創建起委託類和引擎之間的交互渠道,這真是一個使人興奮的設計:)

     下面是NetBpm中的委託類型(建議和ExecutionContext一節一塊兒理解):

  • AssignmentHandler
           實現接口IAssignmentHandler, 它能夠和組織架構中的IT-System相互通訊,用來爲activty-state指定執行者。IAssignmentHandler具備惟一的方法SelectActor(IAssignmentContextassignerContext),其中的assignerContext是其和引擎聯繫的渠道;
  • ActionHandler:實現接口IActionHandler,它用來執行一段流程引擎外完成的程序邏輯,關於action在哪裏執行,何時執行等在流程定義中被定義。actions能夠被看做一系列流程執行事件的偵聽接口,它具備方法Run(IActionContext actionContext),actionContext是它和引擎聯繫的渠道。
  • DecisionHandler:實現接口IDecisionHandler,它用來選擇決定走哪一條transition(邊,見nPdl),具備方法Decide(IDecisionContext decisionContext),該方法返回選擇要走的邊的名稱,decisionContext是其和引擎聯繫的渠道。
  • ForkHandler:實現接口IForkHandler,當執行到fork節點時,Forkhandler用來決定從fork流程的邊中哪些邊須要「forking」。它具備方法Fork(IForkContext forkContext),forkContext是其和引擎聯繫的渠道。注:forkhandler能夠在同一條邊上分散多個forked flow。
  • JoinHandler:實現接口IJoinHandler,當執行到join時,JoinHandler決定是否要激活父flow,它具備方法Join(IJoinContext joinContext),joinContext是其和引擎聯繫的渠道。
  • Serializer:實現接口ISerializer,具備方法Serialize(Object valueObject)和Deserialize(String text),該委託接口負責用來轉換屬性值,把屬性值在.NET-objects(.NET對象)和text-format(文本)之間轉換。其中,text-format(文本)用來存儲屬性值到數據庫中。
  • HtmlFormatter:實現接口IHtmlFormatter,該委託主要用來在屬性值和其相對應的web界面元素之間創建聯繫,同時負責解析web界面元素具備的值。若移植到ASP.NET平臺,該接口建議重寫。
  • ProcessInvocationHandler:實現接口IProcessInvocationHandler,該委託實現收集子流程的初始化數據、收集處理結果、指定完成子流程後要流入的邊等方法,processInvocationContext是其和引擎聯繫的渠道。

................///////////////////////////.............是否要添加委託類的例子


流程定義版本問題

流程定義的名稱與版本

     包含在一個流程定義壓縮包中的信息叫作流程定義。NetBpm中,流程是由字段name來區分的,也就是說引擎根據流程的name來判斷兩個流程是否相等。在流程定義包中不能指定版本,當一個流程定義被引擎加載後,NetBpm將檢查是否有該流程定義的舊版本。若是有,NetBpm將自動設置該新加載進來的流程版本爲全部存在的舊版本流程定義中最高版本數目基礎上加1。

流程執行與版本

     當調用運轉組件獲取流程定義列表方法時,只能獲取到每一個流程的最高版本流程定義。這樣作保證了用戶老是從最新版本的流程定義開始一個流程實例。當新的流程版本加載到NetBpm時,全部正在運行的舊版本的流程實例將保持在原來流程定義方式下運行。

委託類與版本

     關於版本的另一個方面是委託類。不一樣版本流程定義的委託類不是共享的,也就是說每一個流程在執行時只會「看到」它本身流程定義的委託類。 


異常處理機制

     NetBpm做爲一個集成平臺,當流程運行時,確定會依賴公司不少其餘的IT資源,一旦這些依賴致使流程執行時出現錯誤,NetBpm提供了3種解決機制:

  1. 忽略錯誤
  2. 把錯誤日誌記錄下來(默認採用的機制)
  3. 錯誤執行回滾操做(rollback)

    執行回滾機制中,流程實例將會被回滾到執行activity以前的狀態。若是是對NetBpm 調用Eecution Interface時發生流程錯誤,全部的流過的transition(邊)都會執行回滾。


流程定義元素類圖

     關於流程定義的詳細狀況,參見nPdl

 

 


NetBpm中使用的框架或組件

     NetBpm中用到的框架、組件、工具比較多,它們大都是優秀的開源項目。如Castle,NHibernate,Log4Net, NVelocity,NUnit,NAnt等,不要被這些框架嚇倒,實際上,它們僅僅只是「框架」而已:)

IOC容器――Castle

     NetBpm使用了Castle框架,主要用它來實現IOC(控制反轉或者說依賴注入),以依賴注入的方式加載核心組件,如DBClassLoader,流程定義組件,運行組件,日誌組件,組織架構組件,任務調度組件等。在Web程序啓動的時候,根據配置文件,全部的核心組件都將註冊到Caslte IOC容器中,之後當須要使用某個組件的時候,只需利用系統提供的ServiceLocator(服務加載工具類)從容器中獲取實例便可。另外,在任務調度組件中也有用到Castle的Startable Facility(注:你們把facility理解爲注入性質的,對Castle IOC內核容器的功能擴充組件。Castle自己自帶實現了一些faciltiy,開發者也能夠自定義facility),該facitlity主要用來自動運行程序(這裏用來自動間隔掃描任務表,進行任務調度)。

     Castle是.NET平臺下一個功能強大的優秀開源框架,關於Castle的更多信息,請看Castle官方網站。另外TerryLee的博客中關於Castle的中文資源也很豐富。

數據持久層―― NHibernate

     NetBpm中NHibernate組件是做爲Castle的一個facility存在的,它用來實現NetBpm數據持久層, 並方便的實現了事務支持。關於NHibernate的更多信息,請看NHibernate官方網站,關於NHibernate做爲Castle的facility相關請看這裏

示例web層――MonoRail

     你們在Demo演示體驗的時候,必定很奇怪,沒有看到熟悉的.aspx頁面,而是.rails頁面,爲何呢?答案就是NetBPM的Web層採用的是MonoRail框架,而不是咱們熟悉ASP.NET框架。MonoRail是Caslte框架下針對web層編程的一個子框架,它從Ruby Rails獲取靈感而來,採用架構清晰分工明確的MVC模式。NetBPM採用的使用NVelocity做爲頁面解析引擎的MonoRail,它只是對NetBPM核心API的一個Web界面演示示例,用來告訴咱們該怎樣從Web層調用NetBpm API。因此,雖然MonoRail有其獨到之處,可是在其被普及並有好用工具支持以前,咱們只需簡單瞭解下它的運行機制,用以熟悉web層如何利用NetBpm API,不須要了解它太多。用咱們熟悉的ASP.NET實現Web部分顯然是更好的選擇:)。關於MonoRail的更多信息,請看這裏

系統日誌 ――Log4Net

     log4net你們必定不陌生了,NetBpm使用它來記錄系統日誌,關於log4net的更多信息,請看Log4Net官方網站,網上中文資源也很豐富.

單元測試工具――NUnit

     單元測試工具NUnit一直是你們用來單元測試的利器。 NetBPM源碼中已經建有幾個測試工程。關於NUnit的更多信息,請看NUnit官方網站

     注:移植到.NET Framework 2.0下,可能要更改其版本。


後記

     NetBPM的設計無疑是巧妙的,可是現階段的它顯然還不是一個完美的工做流引擎,缺少如JBOSS這樣的強大後盾做支持,中途又趕上強敵WF,NetBPM遠沒有其兄弟JBPM風光,更新沒有它快(JBPM已經出3.0版本了),獲取的支持也少量多, 可是.NET平臺下能有這樣一個優秀的開源工做流項目是十分難得的,若是您正在WF中苦苦掙扎,也許,開源的NetBPM將帶給您一個驚喜:) 

待寫:NetBPM工做流nPdl詳解,一個NetBPM現實生活中請假審批示例

相關文章
相關標籤/搜索