从XOML动态加载工作流活动

时间:2009-11-21 02:00:50

标签: workflow workflow-foundation workflow-activity

我正在尝试实现类似于InvokeWorkflow的活动,它可以动态加载XOML文件,从中实例化活动树,并将其用作唯一的子项。

这与InvokeWorkflow类似,只是动态加载的活动被内联到主工作流程中(从监控角度来看更好)。

我将XamlReader视为一种潜在的方式,但显然它不适合加载工作流程(仅限UI内容)。

谢谢, 于连

2 个答案:

答案 0 :(得分:2)

在这里实现你的目标可能会非常棘手,但是从简单的开始吧: -

您可以使用WorkflowMarkupSerializer命名空间中的System.Workflow.ComponentModel.Serialization从XOML重建工作流程。

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

类似地,您可以使用CompostiteActivityMarkupSerializer重建从CompositeActivity继承的东西中保存的活动的“片段”。

但是,要将新的根活动集成到当前运行的工作流中,需要更多的工作。您需要使用WorkflowChanges类的实例通过修改当前实例使用的工作流定义来创建新活动。

现在,文档是一些粗略的,甚至有点回避这个主题。但是可以收集两个重点: -

  1. 最终需要调用ApplyWorkflowChanges,并且此成员具有protected辅助功能。
  2. 文档表明这需要在工作流的根活动上进行。
  3. 因此,我们可以推断出我们需要一个自定义的根活动来至少协助满足这一要求。

    可能有更多方法可以构建它,但我们假设我们有一个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);
    

    注意我实际上没有测试任何这个,它是从文档中隐藏的信息碎片拼凑而成的。

答案 1 :(得分:1)

非常感谢安东尼。

我不得不说你的动态工作流程修改很酷,但它有点吓人。我最终使用Jon Flander's CallWorkflowActivity的修改来编写工作流程。

我在运行时加载的仅使用XOML的工作流程中学到的一些技巧(使用WF 3.5):

  • 删除XOML中的x:Class属性

  • 删除代码隐藏文件

  • 要让VS设计人员工作,那些XOML文件需要在他们自己的项目中分开(没有代码,例如XOML所在项目中的基本活动或常见类型)

    < / LI>
  • 将XOML标记为VS中的内容并始终复制,以便将其与二进制文件放在一起

  • 即便如此,VS 2008通常需要完整的重建才能正确复制新修改的XOML文件......

  • 您可能需要手动设置断点,如here

  • 所述