Windows Workflow Foundation (WF) 允許在執行期修改工作流實例結構。根據執行位置不同,分為:
WorkflowRuntime 事件中執行(WorkflowCreated、WorkflowSuspended、WorkflowIdled)Initialize 或 Execute 方法中執行static void workflowRuntime_WorkflowCreated(object sender, WorkflowEventArgs e)
{
// 1. 建立 WorkflowChanges,傳入工作流定義(根活動)
WorkflowChanges changes = new WorkflowChanges(e.WorkflowInstance.GetWorkflowDefinition());
// 2. 取得暫時工作流的複本,尋找目標容器活動
CompositeActivity container = changes.TransientWorkflow.GetActivityByName("sequenceActivityContainer") as CompositeActivity;
if (container != null)
{
// 3. 加入新活動
container.Activities.Add(new PrintActivity());
// 4. 驗證變更合法性
ValidationErrorCollection errors = changes.Validate();
if (errors.Count == 0)
{
try
{
// 5. 套用至執行中實例
e.WorkflowInstance.ApplyWorkflowChanges(changes);
}
catch (Exception ex)
{
Console.WriteLine($"動態更新失敗:{ex.Message}");
}
}
else
{
foreach (ValidationError err in errors)
Console.WriteLine($"驗證錯誤:{err}");
}
}
}
在自訂 Activity 中,直接使用 this 取代 e.WorkflowInstance.GetWorkflowDefinition():
// 宿主端寫法
WorkflowChanges wc = new WorkflowChanges(e.WorkflowInstance.GetWorkflowDefinition());
e.WorkflowInstance.ApplyWorkflowChanges(wc);
// 內部寫法(在 Activity 衍生類別中)
WorkflowChanges wc = new WorkflowChanges(this);
this.ApplyWorkflowChanges(wc);
順序工作流與狀態機工作流皆有 DynamicUpdateCondition 屬性(預設為 true)。設為 false 時,呼叫 ApplyWorkflowChanges 會拋出例外,禁止動態更新。
執行後主控台輸出:
beforeSequence執行了
自定義 Print活動
afterSequence執行了
證實 PrintActivity 成功在執行期插入至 sequenceActivityContainer 中。
| 適合場景 | 不適合場景 |
|---|---|
| 運行中流程需新增/移除單一活動 | 整體流程架構大幅變更 |
| 條件式分支需動態調整 | 需重新編譯才能解決的邏輯變更 |
| 不想重新部署即可微調流程 | 版本管控嚴格的生產環境 |
注意:動態更新僅影響目前實例,原始定義與未來實例不受影響。濫用會導致流程難以維護,建議記錄每次變更的審計日誌。