Workflow 从XOML动态加载工作流活动
我正在尝试实现一个类似于InvokeWorkflow的活动,它可以动态加载一个XOML文件,从中实例化一个活动树,并将其用作其唯一的子级 这与InvokeWorkflow类似,不同之处在于动态加载的活动被内联到主工作流中(从监控的角度来看这更好) 我将XamlReader视为实现这一点的一种潜在方法,但显然它不适合加载工作流(仅限于UI内容) 谢谢,Workflow 从XOML动态加载工作流活动,workflow,workflow-foundation,workflow-activity,Workflow,Workflow Foundation,Workflow Activity,我正在尝试实现一个类似于InvokeWorkflow的活动,它可以动态加载一个XOML文件,从中实例化一个活动树,并将其用作其唯一的子级 这与InvokeWorkflow类似,不同之处在于动态加载的活动被内联到主工作流中(从监控的角度来看这更好) 我将XamlReader视为实现这一点的一种潜在方法,但显然它不适合加载工作流(仅限于UI内容) 谢谢, 朱利安在这里实现你的目标可能相当棘手,但是让我们从简单的一点开始:- 您可以使用System.workflow.ComponentModel.Se
朱利安在这里实现你的目标可能相当棘手,但是让我们从简单的一点开始:- 您可以使用
System.workflow.ComponentModel.Serialization
命名空间中的WorkflowMarkupSerializer
从XOML重构工作流
var serializer = new WorkflowMarkupSerializer();
object root = serializer.Deserialize(myXmlReader);
类似地,您可以使用CompositeActivityMarkupSerializer
重构从CompositeActivity继承而来的东西中包含的活动的“片段”
但是,要将新的根活动集成到当前运行的工作流中,需要做更多的工作。您需要使用WorkflowChanges
类的实例,通过修改当前实例使用的工作流定义来创建新活动
现在的文档在这个问题上有些粗略,甚至有点含糊不清。不过,我们可以收集到两个要点:
ApplyWorkflowChanges
,并且该成员具有受保护的
可访问性SequenceActivity
,其中我们有一个自定义的“InvokeWorkflow”活动来执行工作流修改,并且我们打算将生成的新活动放在这个包含序列的末尾
首先,我们需要一个可以在自定义根活动上实现的接口定义:-
internal interface IModifiableWorkflow
{
void ApplyWorkflowChanges(WorkflowChanges workflowChanges);
}
// 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);
在我们的自定义根活动中,我们将显式实现此接口:-
public class CustomSequentialActivity : SequentialWorkflowActivity, IModifiableWorkflow
{
void IModifiableWorkflow.ApplyWorkflowChanges(WorkflowChanges workflowChanges)
{
base.ApplyWorkflowChanges(workflowChanges);
}
}
在自定义“InvokeWorkflow”活动的执行方法中:-
internal interface IModifiableWorkflow
{
void ApplyWorkflowChanges(WorkflowChanges workflowChanges);
}
// 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);
注意,我实际上还没有测试过这些,它是从文档中隐藏的信息碎片拼凑而成的。非常感谢Anthony
我不得不说,您的动态工作流修改很酷,但有点吓人。最后,我使用了对的修改来编写工作流
我从运行时加载的仅XOML工作流(使用WF 3.5)中学到的一些技巧:
- 删除XOML中的x:Class属性
- 删除代码隐藏文件
- 为了让VS设计器工作,这些XOML文件需要在它们自己的项目中分开(在XOML所在的项目中没有代码,例如基本活动或公共类型)
- 将XOML标记为VS中的内容,并始终复制,以便将其与二进制文件放在一起
- 即使如此,VS2008通常需要完全重建,以便正确复制新修改的XOML文件
- 如前所述,您可能需要手动设置断点
链接已断开:(