2009-11-21 40 views
2

我想實現一個類似於InvokeWorkflow的活動,它可以動態加載一個XOML文件,從中實例化一個活動樹,並將其用作其唯一的子對象。從XOML動態加載工作流活動

這與InvokeWorkflow類似,區別在於將動態加載的活動內聯到主工作流中(從監視角度來看這更好)。

我將XamlReader看作是這樣做的潛在方式,但顯然它不適合加載工作流(僅限UI)。

感謝, 朱利安

回答

1

非常感謝安東尼。

我不得不說,你的動態工作流程修改很酷,但它有點可怕。我最終使用修改Jon Flander's CallWorkflowActivity來編寫工作流程。

一些技巧我XOML只工作流程在運行時加載(使用WF 3.5)獲悉:

  • 移去X:在XOML

  • 內部類屬性刪除代碼隱藏文件

  • 對於VS設計人員來說,這些XOML文件需要在他們自己的項目中分開(在XOML所在的項目中沒有代碼,例如基本活動或常見類型)

  • 標記XOML在VS和一直拷貝內容,因此它被放在與您的二進制文件

  • 即使如此,VS 2008通常需要以完全重建正常複製新修改的XOML文件...

  • 您可能需要手動設置斷點,爲解釋here

+0

的鏈接斷開:( – 2016-12-22 23:46:52

2

這裏實現你的目標很可能是相當棘手然而,讓我們開始用簡單的位: -

您可以從XOML使用重建工作流於System.Workflow.ComponentModel.Serialization命名空間中的WorkflowMarkupSerializer

var serializer = new WorkflowMarkupSerializer(); 
object root = serializer.Deserialize(myXmlReader); 

同樣,你可以重構的東西,使用CompostiteActivityMarkupSerializer自CompositeActivity繼承舉行的活動「片段」。

但是,要將新的根活動集成到當前正在運行的工作流中,需要做更多工作。您需要使用WorkflowChanges類的實例,通過修改當前實例使用的工作流定義來創建新活動。

現在的文檔是一些粗略的,甚至有點回避這個問題。兩個重要的點雖然可以收集: - 最終需要

  1. ApplyWorkflowChanges打個電話,這件具有protected可訪問性。
  2. 該文檔表明這需要發生在工作流的根活動上。

因此我們可以推斷出我們需要一個自定義根活動來至少幫助這個需求。

可能有更多的方法可以構造,但讓我們假設我們有一個SequenceActivity其中我們有一個自定義的「InvokeWorkflow」活動執行工作流修改,並且我們打算將最終產生的新活動放在這個包含序列。

首先我們需要一個接口定義,我們可以在自定義的根系活力實現: -

internal interface IModifiableWorkflow 
{ 
    void ApplyWorkflowChanges(WorkflowChanges workflowChanges); 
} 

在我們自定義的根系活力,我們將明確地實現這個接口: -

public class CustomSequentialActivity : SequentialWorkflowActivity, IModifiableWorkflow 
{ 
    void IModifiableWorkflow.ApplyWorkflowChanges(WorkflowChanges workflowChanges) 
    { 
     base.ApplyWorkflowChanges(workflowChanges); 
    } 
} 

在定製「InvokeWorkflow」活動的Execute方法中: -

// Get root activity  
var root = this.Parent; 
while (root.Parent != null) { root = root.Parent; } 

// Create an instance of WorkflowChanges based on the root activity 
var changes = new WorkflowChanges(root); 

//Find the parent sequence activity in the transient workflow definition 
var target = changes.TransientWorkflow.GetActivityByName(this.Parent.Name); 

Activity newActivity = YourCodeToLoadActivityDetailsFromXoml(); 

target.Activities.Add(newActivity); 

//Apply the new changes 
((IModifiableWorkflow)root).ApplyWorkflowChanges(changes); 

注意我沒有真正測試過這些,它們從埋在文檔中的信息碎塊拼湊而成。