2

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

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

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

谢谢,朱利安

4

2 回答 2

2

在这里实现您的目标可能非常棘手,但是让我们从简单的一点开始:-

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

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

同样,您可以使用CompostiteActivityMarkupSerializer.

但是,要将新的根活动集成到当前运行的工作流中需要更多的工作。您需要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);
    }
}

Execute自定义“InvokeWorkflow”活动的方法中:-

// 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);

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

于 2009-11-21T18:46:02.170 回答
1

非常感谢安东尼。

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

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

  • 删除 XOML 中的 x:Class 属性

  • 删除代码隐藏文件

  • 为了让 VS 设计器工作,那些 XOML 文件需要在他们自己的项目中分离(没有代码,例如基本活动或通用类型,在 XOML 所在的项目中)

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

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

  • 您可能需要手动设置断点,如此处所述

于 2009-11-26T20:37:54.090 回答