工作流创作模式
WF中有三种工作流创作模式:
仅限代码:纯使用代码的方式,比如我们创建一个Workflow1.会产生Workflow1.cs和Workflow1.Desiger.cs两个文件。后者是自动生成的。前者是我们
实现逻辑和设计工作流的地方。如果有规则的话,会产生一个序列化的.rules文件。当项目生成的时候,该.rules文件会作为程序集的嵌入式资源。这种
方式在运行时只能通过动态更新来更改.
代码分离:.xoml格式,这种方式的工作流序列化后保存在一个以.xoml为扩展名的文件中,它的代码保存在.xoml.cs中。这种模式在生成的时候会先由
工作流编译器从.xoml文件生成临时的C#类,在和.xoml.cs一起编译。
无代码:只有一个.xoml文件。这种模式在VS模板中是不支持的,在这种模式下只能使用已经存在的工作流类型和成员。请看下图:
从上图中我们可以很清楚的该模式的特点,这种模式有很大的灵活性,可以通过宿主程序将工作流标记文件加载到工作流运行时引擎。不需要重新编
译整个工作流。我们下面来说明如何使用该种方式。
1.首先我们自定义一个工作流基类提供工作流中需要的属性和方法,代码如下:
using System; using System.Workflow.Activities; namespace CaryWFLib { public class CaryBaseWorkflow : SequentialWorkflowActivity { public int Number { get; set; } public void Condition(object sender, ConditionalEventArgs e) { e.Result = (Number > 0); } } }
2.然后我们实现一个自定义活动CaryPrintActivity完成逻辑部分,主要功能输出Message,代码如下:
namespace CaryWFLib { public partial class CaryPrintActivity: Activity { public static DependencyProperty MessageProperty = System.Workflow.ComponentModel.DependencyProperty.Register( "Message", typeof(String), typeof(CaryPrintActivity)); [Description("A string message to write")] [Category("Pro Workflow")] [Browsable(true)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public String Message { get { return ((String)(base.GetValue(CaryPrintActivity.MessageProperty))); } set { base.SetValue(CaryPrintActivity.MessageProperty, value); } } public CaryPrintActivity() { InitializeComponent(); } protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext) { if (Message != null) { Console.WriteLine(Message); } return base.Execute(executionContext); } } }
3.然后我们来实现无代码的工作流部分,代码如下:
<?xml version="1.0" encoding="utf-8" ?> <ns0:CaryBaseWorkflow x:Name="CaryNoCodeWorkflow" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/workflow" xmlns:ns0="clr-namespace:CaryWFLib;Assembly=CaryWFLib"> <IfElseActivity x:Name="ifElseActivity1"> <IfElseBranchActivity x:Name="ifElseBranchActivity1"> <IfElseBranchActivity.Condition> <CodeCondition Condition="{ActivityBind Name=CaryNoCodeWorkflow,Path=Condition}" /> </IfElseBranchActivity.Condition> <ns0:CaryPrintActivity Message="您输入的数字大于0" x:Name="caryPrintActivity1" /> </IfElseBranchActivity> <IfElseBranchActivity x:Name="ifElseBranchActivity2"> <ns0:CaryPrintActivity Message="您输入的数字小于等于0" x:Name="caryPrintActivity2" /> </IfElseBranchActivity> </IfElseActivity> </ns0:CaryBaseWorkflow>
注意
3.1.根节点为ns0:CaryBaseWorkflow,和活动条件的绑定部分。
3.2.无代码的工作流创作模式下不能包含X:Class属性。
3.3.如果规则为声明性规则即.rules的形式,上面的条件部分应该为:
<RuleConditionReferenceConditionName="Condition" />
3.4.需要将该工作流文件属性的生成操作设置为无。
4.宿主部分:
namespace NoCodeWorkflow { class Program { static void Main(string[] args) { using (WorkflowRuntime workflowRuntime = new WorkflowRuntime()) { AutoResetEvent waitHandle = new AutoResetEvent(false); workflowRuntime.WorkflowCompleted += delegate(object sender, WorkflowCompletedEventArgs e)
{ waitHandle.Set(); }; workflowRuntime.WorkflowTerminated += delegate(object sender, WorkflowTerminatedEventArgs e) { Console.WriteLine(e.Exception.Message); waitHandle.Set(); }; Dictionary<String, object> paras = new Dictionary<string, object>(); paras.Add("Number", 2); try { //XmlReader reader = XmlReader.Create("..\\..\\CaryNoCodeWorkflow.xoml"); XmlReader reader = XmlReader.Create("..\\..\\CaryNoCodeRulesWorkflow.xoml"); XmlReader readerRule = XmlReader.Create("..\\..\\CaryNoCodeRulesWorkflow.rules"); //WorkflowInstance instance = workflowRuntime.CreateWorkflow(reader, null, paras); WorkflowInstance instance = workflowRuntime.CreateWorkflow(reader, readerRule, paras); instance.Start(); } catch (WorkflowValidationFailedException ex) { foreach (ValidationError error in ex.Errors) { Console.WriteLine(error.ErrorText); } } catch (Exception ex) { Console.WriteLine(ex.Message); } waitHandle.WaitOne(); } } } }
在宿主程序中,我们使用workflowRuntime.CreateWorkflow的另一种重载。最后结果如下: