前言:流程實現基本流轉功能外,通常也需要調用外部事件,用於和業務系統的交互,同時存儲一些流程變量,用於追蹤和記錄業務數據變化對流程流轉的影響。
1. 流程事件
流程執行過程中,伴隨各種事件的發生,而且是存在於整個流程的生命周期,即從流程啟動一直到流程結束的整個過程都有事件發生。這些事件的發生,業務系統通常也需要知道一些流程過程的關鍵節點,或里程碑狀態。我們統稱為流程事件。
1.1 流程事件觸發類型
流程事件類型的定義是按照事件發生的位置來確定划分,跟流程直接有關的比如有:啟動、運行、撤銷、退回、返送、跳轉、返簽和結束等。而跟活動有關的事件類型有:創建、執行和結束等。我們可以用下圖來描述常見的事件觸發:

1.2 流程事件觸發實現
流程事件的觸發,是按照先訂閱,后觸發的機制來實現。訂閱(Subscribe)是流程服務接口開放出來的方法,可以直接在這個方法里面注冊匿名函數來綁定事件。程序代碼如下:
IWorkflowService wfService = new WorkflowService();
var wfResult = wfService.CreateRunner(runner.UserID, runner.UserName)
.UseApp(runner.AppInstanceID, runner.AppName, runner.AppInstanceCode)
.UseProcess(runner.ProcessGUID, runner.Version)
.NextStep(runner.NextActivityPerformers)
.IfCondition(runner.Conditions) //condition on the transiton
.Subscribe(EventFireTypeEnum.OnActivityExecuting, (activityInstanceID, activityCode, delegateService) => {
if (activityCode == "Task1")
{
delegateService.SetVariable("name", "book-task1");
delegateService.SetVariable("amount", "50");
}
return true;
})
.Run();
2. 事件類型節點
BPMN規范里面,涉及到事件類型的節點,雖然不同於任務類型的節點,但是事件類型的節點通常都是表示一種流程的狀態,比如流程的開始和結束是最基本的兩個狀態。中間事件(Intermediate Event)是本次我們主要涉及到的事件類型的節點,其它事件類型的節點將在后期的文章中描述到。
2.1 中間事件(Intermediate Event)
中間事件(Intermediate Event)類型的節點一般用於流程中間狀態的變換,而且可以作為流程里程碑的事件或狀態觸發,用於通知業務系統流程的里程碑狀態已經發生,或者也可以收到業務系統的反饋的信息,用於一些流程下一步路徑的解析。
比如在中間事件觸發時,只有從業務系統中讀取到業務變量,然后傳入流程的下一步分支選擇條件變量中,才能確定下一步的流轉路徑。這樣的處理過程是經常的一種業務場景。一個有中間事件類型節點的流程圖示意如下:

2.2 節點上事件的定義
在流程設計器中,節點上的事件定義主要有兩個屬性:事件觸發的位置(執行前和執行后)、以及事件執行的表達式。一個定義示例描述如下:
觸發位置:執行前
表達式:Slickflow.Module.External.OrderSubmitService
2.3 業務服務的代碼實現
上文中提到的表達式是業務服務的程序代碼,業務服務的邏輯實現,除了本身的功能代碼實現,還需要繼承如下的兩個接口: ExternalServiceBase 和 IExternalService。 主要用於明確定義Execute()執行方法,然后在引擎內部執行過程中,在調用和執行這個接口方法。具體代碼示例如下:
/// <summary>
/// 訂單提交服務類(對應訂單流程中訂單提交節點)
/// </summary>
public class OrderSubmitService : ExternalServiceBase, IExternalService
{
/// <summary>
/// 業務邏輯前置調用方法
/// </summary>
public override void Execute()
{
//實現用戶自己的業務邏輯
var id = DelegateService.GetID();
var amount = DelegateService.GetVariable("amount");
DoSomethingElse(amount, 20);
}
/// <summary>
/// 業務邏輯具體實現方法
/// </summary>
/// <param name="amount"></param>
/// <param name="newAmount"></param>
private void DoSomethingElse(string amount, int newAmount)
{
var intAmount = 0;
int.TryParse(amount, out intAmount);
if (intAmount < newAmount)
{
DelegateService.SetVariable("amount", newAmount.ToString());
}
//調用其它業務處理邏輯
var session = DelegateService.GetSession();
//實現其它數據庫業務邏輯
//.............................
}
}
3. 委托服務的內部機制
委托服務用於統一處理所有流程發生的時間,跟事件交互過程中,除了觸發事件本身以外,還要考慮引擎內部和外部業務系統之間的交互。比如流程變量的保存和讀取就是一種交互應用。
3.1 委托服務接口
委托服務接口定義出事件訂閱時候的接口類型,具體代碼如下:
/// <summary>
/// 委托接口
/// </summary>
public interface IDelegateService
{
int ID { get; set; }
int GetID();
IDbSession GetSession();
string GetVariable(string name, Nullable<ScopeTypeEnum> scopeType = null);
void SetVariable(string name, string value, Nullable<ScopeTypeEnum> scopeType = null);
string GetCondition(string name);
void SetCondition(string name, string value);
T GetInstance<T>(int id) where T : class;
}
3.2 委托服務繼承類
繼承委托服務的接口實現目前有兩種類型,一是流程委托服務接口,而是活動委托服務接口。實現的主要目的是對流程變量的讀取和存儲,還有給外部應用展示流程實例的關鍵信息。
4. 流程變量
流程變量是流程流轉過程發生的一些數據變化,這些變量一般是來自業務系統的關鍵參數,而且在流程流轉時,通過條件表達式傳入,可以決定流程流轉下一步的路徑選擇。
4.1 流程變量類型
流程變量類型分為全局變量和局部變量。在程序中也可以命名為流程變量(ProcessVariable)和活動變量(ActivityVariable)。
4.2 流程變量存儲
流程變量的存儲是持久化存儲在數據庫表(WfProcessVariables)中,變量名和數值的key-value是其記錄格式。
delegateService.SetVariable("name", "book-task1");
delegateService.SetVariable("amount", "50");
5. 總結
流程引擎跟外部事件的交互實現,可以豐富業務過程的狀態變化和響應,通過流程變量的存儲,記錄業務過程中的關鍵數據變化,同時也做到了對流程分支選擇的路徑跟蹤。程序開發人員可以通過實現外部事件的委托服務,然后再訂閱流程過程事件,來徹底實現業務系統跟引擎內部的進一步協作整合。
