WF学习系列之二:开发工作流知识点概述
注:本文从msdn中摘录而成,主要提供有关创建工作流时的可用功能的概念性信息。主要介绍以下15个方面:
1 工作流创作样式 :主要包括顺序工作流、状态机工作流、数据驱动工作流。
2 工作流创作模式 :分为三种,包括仅限代码、代码分离、无代码。典型的用法是使用设计器定义工作流,使用代码表示业务逻辑。
3 使用活动控制流 :使用一些活动来控制工作流的逻辑流。
4 在工作流中使用条件 :利用条件来控制工作流的行为。
5 在工作流中使用 RuleSet :规则的定义,需要好好研究,也是非常关键的一个知识点。
6 使用工作流中的事务 :通过TransactionScopeActivity, CompensatableTransactionScopeActivity活动来支持事务故障恢复。
7 工作流中的批处理状态信息 :通过IWorkBatch 和 IPendingWork 来获取服务和工作流实例保留状态信息。
8 工作流中的错误处理 :详见《WF学习系列之一》
9 在工作流中使用补偿 :详见《WF学习系列之一》
10 在工作流中使用工作流更改 :重点了解什么情况下适合更改工作流,有什么限制条件等。
11 工作流中的数据交换 :详见《WF学习系列之一》
12 在工作流中使用角色 :WF 提供了一种用于对所有支持数据输入的活动的、基于角色的访问机制。
13 如何:编译工作流 :根据工作流创作模式的不同,编译的方式也有区别。
14 如何:序列化工作流 :序列化和反序列化是实现工作流持久化的基础。
15 使用工作流标记 :使用可扩展应用程序标记语言 (XAML) 创建标记源文件从而创建工作流的声明性方式。
1 工作流创作样式
Windows Workflow Foundation 支持多种工作流创作样式,如顺序、状态机和数据驱动。 顺序样式非常简单,对于总是相同的重复、可预测操作很有用。 状态机工作流样式包含一组事件驱动状态。 数据驱动样式依赖数据来确定是否基于本地数据状态来运行某些活动。
顺序工作流
顺序工作流样式按逐个顺序执行一组包含的活动。 您可以向顺序工作流添加其他复合活动以实现并行 (ParallelActivity)、事件驱动并行 (EventHandlingScopeActivity)、数据驱动执行 (ConditionedActivityGroup)、事件驱动分支 (ListenActivity) 和熟悉的强制性控制流模式,如条件分支 (IfElseActivity) 和迭代(WhileActivity、ReplicatorActivity)。 您也可以利用 Windows Workflow Foundation 的扩展性编写自定义复合活动,用这些活动实现您的解决方案需要的特定控制流模式。
下面的流程图显示一个顺序工作流的示例。
顺序工作流按顺序方式执行活动,直到最后一个活动完成。 即使在正常操作下,顺序工作流也不必是完全确定的。 例如,您可以使用 ListenActivity 活动或 ParallelActivity 活动,在这两种情况下事件的准确顺序可以不同。
状态机工作流
在工作流创作的状态机样式中,作者将工作流建模为状态机。 工作流本身由一组状态组成。 将一个状态指示为初始状态。 每个状态都可以接收一组特定事件。 视事件而定,可以转换到另一个状态。 状态机工作流可以有最终状态。 当对最终状态进行转换时,工作流将完成。
下面的流程图是一个状态机工作流的示例。
活动 |
说明 |
用于依赖于外部事件开始执行的状态。 EventDrivenActivity 活动必须具有实现 IEventActivity 接口作为第一个子活动的活动。 有关更多信息,请参见使用 EventDrivenActivity 活动。 |
|
指定到新状态的转换。 有关更多信息,请参见使用 SetStateActivity 活动。 |
|
表示状态机中的一个状态;可能包含其他 State 活动。 有关更多信息,请参见使用 StateActivity 活动。 |
|
在进入某个状态时执行;可能包含其他活动。 有关更多信息,请参见使用 StateInitializationActivity 活动。 |
|
在离开 StateActivity 活动时执行包含的活动。 有关更多信息,请参见使用 StateFinalizationActivity 活动。 |
2 工作流创作模式
Windows Workflow Foundation 默认将工作流定义与业务逻辑相分离。 在典型的工作流创作方案中,工作流创建者可以使用设计器来指定工作流定义,然后使用 C# 或 Visual Basic 代码来表示业务逻辑。 这种创作模式称为“代码分离”。
Windows Workflow Foundation 支持以下针对工作流实现的创作模式:
仅限代码。 这是 Windows Workflow Foundation 的默认创作模式。 在该模式下,可以使用 C# 或 Visual Basic 代码来指定使用 Windows Workflow Foundation API 集的工作流。 在仅限代码的工作流中,工作流定义使用 C# 或 Visual Basic 代码来声明工作流结构。 仅限代码的工作流必须进行编译。
代码分离。 在此模式下,可以通过使用工作流标记并将其与 C# 或 Visual Basic 代码隐藏实现进行组合来定义工作流,这与 ASP.NET 模型类似。 与无代码创作模式不同,代码分离的工作流必须进行编译,并且无法直接加载到工作流运行时引擎。
无代码。 在此模式下,可以通过使用工作流标记来创作工作流。然后可以使用 Windows Workflow Foundation 命令行工作流编译器来编译工作流,也可以通过宿主应用程序将工作流标记文件加载到工作流运行时引擎。
3 使用活动控制流
Windows Workflow Foundation 包含一组可提供各种功能的活动。 使用其中的一些活动可以控制工作流的逻辑流。 有关 Windows Workflow Foundation 基本活动库中的活动的完整列表,请参见 Windows Workflow Foundation 活动。
下表列出了 Windows Workflow Foundation 基本活动库中可用于控制工作流逻辑流的活动。
活动 |
说明 |
允许工作流根据某种事件或超时期限到期,进行条件分支。 有关更多信息,请参见使用 ListenActivity 活动。 |
|
测试每个分支条件,在第一个条件为 True 的分支上执行活动。 有关更多信息,请参见使用 IfElseActivity 活动。 |
|
允许工作流执行相互独立的两个或更多操作。 有关更多信息,请参见使用 ParallelActivity 活动。 |
|
挂起工作流的操作,以便能够在出现某种错误条件时进行干预。 有关更多信息,请参见使用 SuspendActivity 活动。 |
|
用于在出现某种错误条件时立即结束工作流的操作。 有关更多信息,请参见使用 TerminateActivity 活动。 |
|
使工作流能够在条件得到满足之前进行循环。 有关更多信息,请参见使用 WhileActivity 活动。 |
|
也称为 CAG。 根据应用于 CAG 本身的条件以及分别应用于每个子活动的条件来执行子活动。 有关更多信息,请参见使用 ConditionedActivityGroup 活动。 |
|
包装另一个活动,并在发生指定事件时执行该活动。 有关更多信息,请参见使用 EventDrivenActivity 活动。 |
|
创建和执行子活动的多个实例。 有关更多信息,请参见使用 ReplicatorActivity 活动。 |
|
根据一种已定义的排序方式,运行一组子活动。 有关更多信息,请参见使用 SequenceActivity 活动。 |
4 在工作流中使用条件
可以使用条件来控制工作流的行为。 运行时引擎计算条件的值,然后根据计算结果执行操作。
有两种方法可以在工作流中表示条件:
在代码中可以通过编写处理程序来表示条件,该处理程序为条件设置 Result 属性。
还可以将条件表示为规则条件,规则条件是规则文件中的 System.CodeDom 表达式。
条件活动
随 Windows Workflow Foundation 一起提供的几个活动使用以下条件:
第一个是 IfElseBranchActivity,它包含在 IfElseActivity 活动中,在具有的条件计算结果为 True 时执行。
只要 WhileActivity 活动的条件计算结果为 true,它就会连续执行所包含的任何活动。 每次循环完成时重新计算该条件。
ConditionedActivityGroup 连续执行所包含的任何活动,直到其条件计算结果为 true。 ConditionedActivityGroup 中的每个单个活动都具有 When 条件。 仅当 When 条件计算结果为 true 时才执行各个活动。
ReplicatorActivity 在其 UntilCondition 属性计算结果为 true 时完成执行。
也可以在您创建的自定义活动中使用条件。
注意:
规则条件和代码条件可以引用在工作流类中定义的公共、私有和内部成员。
5 在工作流中使用 RuleSet
RuleSet 由一个或多个规则条件及其导致的操作组成。可以将规则视为 IF-THEN-ELSE 语句,其中,条件对应于 IF,而操作定义 THEN 和 ELSE 子句的行为。
操作可以执行以下任务:
· 设置工作流上的字段或属性。
· 调用工作流上或工作流中的对象上的方法。
· 调用被引用程序集中的类型上的静态方法。
· 执行 Halt 或 Update 语句。
· Windows Workflow Foundation 规则引擎设计为以基于优先级的方式运行规则并且支持正向链接。
6 使用工作流中的事务
Windows Workflow Foundation 通过使用 TransactionScopeActivity 活动包装 .NET Framework System.Transactions 事务(如果发生错误,这些事务会自动回滚它们的操作)来支持从事务故障恢复。有关 System.Transactions 的更多信息,请参见 .NET Framework System.Transactions.Transaction 和 System.Transactions.TransactionScope 类及 MSDN 库中的相关类型。
CompensatableTransactionScopeActivity 活动像 TransactionScopeActivity 活动一样对事务进行包装,只不过前者还支持补偿。
7 工作流中的批处理状态信息
工作流定期在各个检查点(称为持久性点)将其状态保存到持久性存储中。 如果在工作流中出现错误,则可能需要运行时引擎检索保留的该信息以恢复稳定状态。 如果两个或多个组件正在进行通信,则通常情况下,最好协调持久性存储以便组件的状态保持一致。 工作流的外部服务使用工作批次来保留状态信息。 这些服务对其工作项进行批处理并共享与工作流的事务相同的事务。如果工作流尚未提交事务,则服务仍可以在持久点期间对某些工作项进行批处理。
Windows Workflow Foundation 提供 IWorkBatch 和 IPendingWork 以帮助服务和工作流实例保留状态信息。
在对从工作流初始化的服务进行的所有调用中,运行时引擎在其线程调用上下文中提供一个 IWorkBatch。 服务可以将挂起的工作项添加到此工作批次,以便运行时引擎可以在单个事务中提交所有相关的工作项。
若要将工作项添加到批次中或向批次注册,请使用下面的语句:
WorkflowEnvironment.WorkBatch.Add(IPendingWork work, object workItem);
此外,还可以将 IPendingWork 传入 ExternalDataEventArgs 的构造函数。
调用组件时的操作顺序
1) 在初始化期间,工作流创建一个工作批次。
2) 工作流将工作批次附加到对组件的方法调用中。通过使用 WorkflowEnvironment 类,服务可以访问其任何方法中的工作批次。
提交点处的操作顺序
1) 工作流创建一个事务。
2) 工作流循环访问工作批次并收集组件的所有工作项(保持顺序)以创建工作批次。工作流传入事务和工作批次,调用组件上的 Commit 方法。
3) 组件将工作批次中的工作添加到事务。
4) 对工作项在工作批次中的所有组件重复第 2 步和第 3 步。
5) 当 Commit 通知成功时,工作流提交对应的事务。
6) 成功提交事务后,工作流循环访问工作批次并收集每个组件的所有工作项(如第 2 步所述)。工作流传入对应的事务和工作批次,调用每个组件的 Complete 方法。
对工作流错误的操作顺序
1) 工作流标识所有与出错范围相关的工作项并构建一个工作批次。
2) 工作流调用每个唯一的、将工作批次中所有工作的完成状态设置为 false 的 IPendingWork 的 Complete 方法。
3) 如果工作批次属于 TransactionScopeActivity 活动或 CompensatingTransactionScopeActivity 活动的子上下文,则工作流放弃工作批次中的所有工作。
4) 从错误恢复后,运行时保持对所有剩余工作批次项的引用。随后,可能会在将来的持久点提交该工作。
重试工作批次事务
DefaultWorkflowCommitWorkBatchService、SharedConnectionWorkflowCommitWorkBatchService、SqlWorkflowPersistenceService 和 SqlTrackingService 都具有重试工作批次提交的功能。 此功能通过 EnableRetries 属性启用,它使这些服务能够在网络超时、计算机重新启动、SQL Server 进程重置等情况下一直尝试提交工作批次。重试次数设置为 20。前三次重试会依次紧接着发生。 此后,每个后续重试之间都有一段延迟。 应用程序可以在其连接字符串中调整连接超时以部分地调整重试的时间间隔。可以通过编程方式或配置文件设置此属性。有关如何通过编程方式设置此属性的更多信息,请参见每个服务的 EnableRetries 属性。 有关如何通过配置文件设置此属性的更多信息,请参见Workflow Configuration Files。
8 工作流中的错误处理
Windows Workflow Foundation 中的错误处理指的是以异步方式处理异常。 这意味着工作流运行时引擎会捕获在活动中(显式或隐式)引发的异常,然后将其安排在队列中以便以后处理。这与常规异常处理不同,因为在常规异常处理中,如果异常是在 try 块中引发的,则它可以由相应的 catch exception 块捕获,也可以立即对用户引发。详见《WF学习系列之一》
9 在工作流中使用补偿
已完成事务的 Windows Workflow Foundation 补偿模型是一个处理工作流中发生的任何业务异常并合乎逻辑地撤消已完成事务的过程。详见《WF学习系列之一》
10 在工作流中使用工作流更改
工作流更改使您可以在运行时对正在运行的工作流实例进行更改。 这些更改可能由设计时的省略、对活动的属性和绑定的更改,或对增强和更完整地模拟业务过程的业务逻辑的需要而激发。 工作流更改不适合要进行整体更改的情况,因为这将导致工作流与原始设计原则产生极大差别。在此类情况下,应设计一个新的工作流,而不是对正在运行的实例进行更改。
工作流更改适用于工作流的单个实例。 工作流更改不支持基于类型的更改,基于类型的更改会复制到给定工作流类型的所有正在运行的实例和将来的实例。
可以使用工作流更改执行以下操作:
· 更改工作流结构,例如添加或移除活动。
· 更改流控制。
以下是一些常见的工作流更改的示例:
· 更改由 PolicyActivity 活动使用的 RuleSet。
· 更新 RuleCondition 定义,以更改分支活动(如 ConditionedActivityGroup 和 IfElseActivity)的行为。
· 添加新的自定义活动或 InvokeWorkflowActivity 活动(如果在部署和开始运行工作流之后,必须向该工作流中添加新的业务过程)。
· 在工作流的外部使用工作流标记以声明方式创作更改,并接受将更新的标记作为参数来进行更改。
· 添加新的 EventDrivenActivity 活动以响应新事件,例如其他批准步骤。
将工作流更改应用于正在运行的工作流可能会在两个不同的入口点发生:在工作流代码文件中和工作流外部(如工作流宿主)。
工作流更改的限制
以下是由 Windows Workflow Foundation 实施的工作流更改的一些限制,您必须清楚这些限制:
· 可以添加或移除工作流实例中的活动,但无法更改现有活动的属性,除非这些属性是声明性规则条件或规则集。
· 将子活动作为其定义的一部分加入的自定义复合活动类型不能包含动态添加或移除的子活动。 这是因为,类似这样的自定义复合活动是“黑盒”活动,不能在运行时期间进行根本修改。
· 运行时期间,无法动态移除不处于 Initialized 或 Closed 状态的活动。
· 工作流开发人员可以通过附加到工作流的根活动的 ActivityCondition 来限制对工作流更改的使用,工作流的根活动由工作流运行时用于确定是否允许对特定的工作流实例进行任何工作流更改。
自定义复合活动可以验证建议的更改,例如添加或移除子活动。 这使活动开发人员可以确定是否任何建议的工作流更改与其活动的预期功能相冲突。此功能通过自定义 ActivityValidator 提供,开发人员可以在其中重写 ValidateActivityChange 方法并添加其自定义的工作流更改验证逻辑。
11 工作流中的数据交换
Windows Workflow Foundation 通信服务支持在工作流与其宿主环境之间进行数据交换。通过 Windows Workflow Foundation 通信服务,工作流可以使用 HandleExternalEventActivity 和 CallExternalMethodActivity 类以及支持 ExternalDataExchangeAttribute 属性的接口与本地宿主交换数据。详见《WF学习系列之一》
12 在工作流中使用角色
Windows Workflow Foundation 提供了一种用于对所有支持数据输入的活动的、基于角色的访问机制。 工作流创建者可以完全控制如何创建角色和角色集合。这样将使创建者能够提供必要的授权机制,在执行活动之前验证调用者的角色。
某些 Windows Workflow Foundation 活动(如 WebServiceInputActivity 和 HandleExternalEventActivity)提供用于获取或设置角色集合的属性。
为了使用 Active Directory 来帮助开发工作流,Windows Workflow Foundation 提供了一种现成可用的机制来创建支持 Active Directory 的角色。 有关基于 .NET Framework 安全性和 Active Directory 的信息,请参见 MSDN Library。
有关角色的更多信息,请参见 Windows Workflow Foundation 类库参考中的 System.Workflow.Activities 命名空间的 WebWorkflowRole、WorkflowRole 和 ActiveDirectoryRole 类。
13 如何:编译工作流
您可以通过三种方法来构造工作流:
· 以声明方式在文件名为 extension .xoml 的工作流标记文件中使用工作流标记。 然后,可使用工作流编译器编译该工作流文件,或者不对它进行编译,而通过主机应用程序将它传递到工作流运行时引擎中。 这称为“无代码工作流创作”。 有关更多信息,请参见使用工作流标记。所创建的文件使用的文件扩展名为 .xoml。
· 标记文件可用于声明工作流,但之后会使用包含实现逻辑的代码文件对它进行编译。 这称为“代码分离工作流创作”。 在这种情况下,所创建的文件使用的文件扩展名为 .xoml 和 .xoml.cs 或 .xoml.vb。
· 在代码文件中使用 Windows Workflow Foundation 对象模型。 这称为“仅限代码工作流创作”。 在这种情况下,所创建的文件使用标准的 C# 或 Visual Basic 源代码文件扩展名。 此外,也会对这些文件进行编译。
编译过程
编译工作流时,会在编译过程中执行下列过程:
· 执行验证可以确保根据工作流活动为自己设置的规则验证这些活动。 如果存在验证错误,则编译器会返回错误列表。
· 根据在编译器中输入的标记定义来生成一个分部类。
· 执行代码可以帮助在运行时执行活动。 生成事件订阅,事件订阅可帮助活动了解它们所包含的活动何时执行完毕。
· 在 .NET Framework C# 或 Visual Basic 编译器中输入根据标记文件生成的分部类以及根据代码文件生成的分部类。此过程的输出为 .NET 程序集:WorkflowSample.dll。 可以部署该程序集以运行工作流。
使用 wfc.exe 工作流命令行编译器
Windows Workflow Foundation 提供一个名为 wfc.exe 的命令行工作流编译器。 Windows Workflow Foundation 还提供一组公共类型,这些类型支持编译工作流以开发自定义编译器。 这些公共类型与 wfc.exe 在内部使用的类型相同。您可以使用 WorkflowCompiler 类来创建编译器的自定义版本。
也可以使用 WorkflowCompiler 类来编译工作流,如下面的简单示例所示。
WorkflowCompiler compiler = new WorkflowCompiler();
WorkflowCompilerParameters param = new WorkflowCompilerParameters();
compiler.Compile(param, new string[] { "MainWorkflow.xoml" });
有关更多信息,请参见 Windows Workflow Foundation 类库参考中的 WorkflowCompiler 类。
编译器选项
对于 wfc.exe 工作流命令行编译器选项,将在以下代码样式的主题中进行介绍。
14 如何:序列化工作流
Windows Workflow Foundation 框架提供用于序列化和反序列化工作流的序列化基础结构。 默认情况下,工作流依据某些格式规则序列化为工作流标记。
默认序列化
新活动的开发人员自动拥有序列化为工作流标记的默认功能。 此默认序列化功能对于大多数活动应该是够用的,但有时也可能需要自定义序列化程序。
下面的示例演示如何使用 WorkflowMarkupSerializer 类来序列化工作流。
using System.Xml;
using System.IO;
using System.Workflow.ComponentModel.Serialization;
using System.Globalization;
...
// In the implementation of your host application, create a sequential workflow.
SequentialWorkflowActivity workflow1 = new SequentialWorkflowActivity();
// Construct workflow.
...
// Serialize workflow.
WorkflowMarkupSerializer serializer = new WorkflowMarkupSerializer();
StringWriter strWriter = new StringWriter(CultureInfo.InvariantCulture);
XmlWriter xmlWriter = XmlWriter.Create(strWriter);
serializer.Serialize(xmlWriter, workflow1);
// Create a log file, open it, and write the serialized workflow to it.
File.WriteAllText(@"C:"logfile.txt", strWriter.ToString());
序列化基础结构
Windows Workflow Foundation 的默认序列化基础结构提供序列化默认活动所需的全部类型。 有关 Windows Workflow Foundation 框架的默认活动集的信息,请参见 Windows Workflow Foundation 活动。
下面是序列化基础结构中的重要类:
· WorkflowMarkupSerializer 类是序列化基础结构中使用的序列化基类型。 此类型为序列化提供一些实现序列化规则的基本服务。 活动的序列化程序或者用于自定义活动的其他任何自定义序列化程序必须从此类继承。
· ActivityMarkupSerializer 类从 WorkflowMarkupSerializer 类继承。 此类型用于序列化所有基本活动。 基本活动是复合活动之外的活动。
· CompositeActivityMarkupSerializer 类从 ActivityMarkupSerializer 类继承,它为复合活动提供序列化。CompositeActivityMarkupSerializer 增加更多方法以处理子活动,子活动可以使用它们自己的序列化提供程序来序列化。
序列化格式规则
工作流标记是对象层次结构的序列化形式。 对象的序列化方式取决于对象的属性。 有两个主要规则来帮助完成类型实例的序列化:
· 对象的类型定义是 XAML 中的元素名称。
· 对象的属性 (Property) 映射到 XAML 中的元素定义的属性 (Attribute)。
下面的代码示例举例说明对象序列化。
public Class ExampleActivity : Activity
private string property1 = "SomeValue";
private string property2 = "SomeOtherValue";
public string ExampleProperty
{
get { return property1; }
set { property1 = value; }
}
public string ExampleOtherProperty
{
get { return property2; }
set { property2 = value; }
}
// Activity.Execute and other overridden methods not included for clarity.
}
该类的实例如下面的 XAML 代码示例所示进行序列化。
<ns0:ExampleActivity ExampleOtherProperty="SomeOtherValue" x:Name="ExampleActivity" ExampleProperty="SomeValue" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:ns0="clr-namespace:CustomWFActivities;Assembly=CustomWFActivities, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
该代码示例演示两个字符串属性 (Property) ExampleProperty 和 ExampleOtherProperty 成为了 ExampleActivity 元素的属性 (Attribute)。 值“SomeValue”和“SomeOtherValue”是两个字段的实际值。
当然,类定义可能比代码示例的 ExampleActivity 类要复杂得多。 在更复杂的对象的序列化方面,存在其他规则。
注意:
WorkflowMarkupSerializer 不支持对嵌套类型进行序列化。 例如,如果您创建一个自定义活动并在该活动内定义嵌套类型,则您将在编译时收到错误
自定义序列化
可以自定义序列化格式。 可以在两个级别进行自定义。 可以提供一个全新的序列化基础结构,这包括一个自定义序列化格式以及分别对应于每个类型的序列化。可在活动级别进行其他序列化。 序列化基础结构仍然是由 Windows Workflow Foundation 创作框架提供的工作流标记,但各个活动布局可以更改。
自定义活动
如果您创建一个自定义序列化程序,则活动作者必须提供对该自定义序列化程序的引用,具体如下面的代码示例所示。
[DesignerSerializer(typeof(ExampleActivityMarkupSerializer), typeof(WorkflowMarkupSerializer))]
public class ExampleActivity : Activity
{
}
序列化程序通过使用 DesignerSerializer 属性来指定,该属性具有两个参数:
· 第一个参数指定应当用来序列化定义了该属性的类的实例的序列化程序。
· 第二个参数指定序列化程序的基类型。 序列化程序的基类型指定要使用的序列化方案。
在 DesignerSerializer 代码示例中,第二个属性指定 WorkflowMarkupSerializer。 这意味着要使用的基本序列化基础结构基于 WorkflowMarkupSerializer。
定义自定义序列化程序
自定义序列化程序是必须从序列化基类型继承的类。 在 DesignerSerializer 代码示例中,ExampleActivityMarkupSerializer 是 ExampleActivity 类的自定义序列化程序。 ExampleActivityMarkupSerializer 从 WorkflowMarkupSerializer 继承,后者是该属性的第二个参数。
当序列化管理器开始序列化活动时,它使用类定义来确定自定义序列化程序类型,方法是:在 DesignerSerializer 属性的第二个参数中查找 WorkflowMarkupSerializer 的基类型。 然后获得该序列化程序的一个实例并使用它。
工作流标记
工作流标记描述可以由 Windows Workflow Foundation 运行时引擎执行的工作流。工作流标记是序列化方案的一部分,用于描述构成工作流的活动层次结构以及在活动引发事件时激活的关联逻辑。
工作流标记没有任何固定的语法来描述它。 它定义可用于表示对象层次结构以及对象的属性和方法的通用方案。每个活动都有序列化逻辑,这样便可以在为对象定义的标记中表示活动元数据。
15 使用工作流标记
Windows Workflow Foundation 为设计人员和开发人员提供了一种通过使用可扩展应用程序标记语言 (XAML) 创建标记源文件从而创建工作流的声明性方式。 可以将这些标记文件编译到工作流类型中,在运行期间直接加载到工作流运行时引擎中,也可以将这些标记文件与以 C# 或 Visual Basic 实现的代码隐藏文件一同编译到工作流类型中。 这意味着工作流标记文件编译与否均可,具体取决于业务原因以及是否需要额外的实现逻辑。 使用工作流标记与代码隐藏逻辑文件类似于 ASP.NET 将演示文件与逻辑文件相分离的方式。
有关如何将工作流标记文件直接加载到工作流运行时引擎的示例,请参见创建工作流宿主应用程序主题。
除了在工作流标记中创建工作流之外,以 WorkflowPersistenceService 服务保持工作流时也可以使用工作流标记,这是因为用 WorkflowMarkupSerializer 对编程工作流进行序列化后,这些工作流就变成了工作流标记。 有关更多信息,请参见如何:序列化工作流和 Windows 工作流持久性服务。
基本结构
工作流标记的基本结构包括根节点,表示工作流的类型;接下来是该工作流中的子活动,作为嵌入的子元素。 由于工作流标记基于 XAML 元素和属性的子集,因此工作流标记文件的结构类似于 XAML 文件的结构。 例如,工作流中的每个元素都表示为复合活动或工作流本身的节点。 节点之间的关系将得到保留,就像通过编程语言(如 C# 或 Visual Basic)创建工作流时的那样。
元素和属性
如前所述,工作流标记文件中的每个元素都与某个工作流组件相对应。这些元素的名称与以编程方式创建工作流时所使用的活动类型的名称相同。 例如,IfElseActivity 活动由 <IfElseActivity> 元素表示。对自定义活动也是如此。
对活动成员以下例中所示方式进行声明:
<SampleActivity Property1="PropValue" Method="CustomMethod" Event="EventHandlerMethod"/>
通过 XAML 还可以使用 x:Code 指令元素在工作流标记文件中插入过程代码。代码必须位于 CDATA 节中,以使编译器可以编译代码而非将其视为声明性 XAML 标记。 以下示例显示如何将该元素用于 CDATA 节。
<CodeActivity x:Name="codeActivity1" ExecuteCode="methodName1">
<x:Code><![CDATA[
void methodName1(object sender, EventArgs e)
{
}
]]></x:Code>
</CodeActivity>
注意:
只能在已编译的工作流标记文件中使用 x:Code 指令元素。
属性 |
说明 |
x:Array |
类型的数组。 |
x:Class |
工作流类的名称,包括命名空间。 编译工作流时创建此名称的类。 |
x:Name |
活动的名称。 与 Activity.Name 属性相对应。 |
x:Type |
类型引用。 |
x:Null |
Null 值。 |
xmlns:x |
XAML 架构的命名空间。 |
xmlns |
工作流 XAML 架构的命名空间。 |
注:如果使用非编译、仅 XAML 的工作流标记文件创建工作流,则 XAML 文件中不应出现 x:Class 属性。 只有在编译工作流时此属性才有效。
如果创建工作流标记文件后更改了 VB 应用程序的根命名空间,则也必须更新该工作流的 x:Class 属性。
posted on 2008-12-09 22:37 mjgforever 阅读(2417) 评论(2) 编辑 收藏 举报