目的

 这篇指导资料的目的是介绍Workflow的所有概念,指导你如何使用它,并且保证你逐步理解Workflow的关键内容。
本指导资料假定你已经部署Workflow的范例应用在你的计算机上。范例应用部署是使用基于内存的数据存储,这样你不需要担心如何配置其他持久化的例子。范例应用的目的是为了说明如何应用Workflow,一旦你精通了Workflow的流程定义描述符概念和要素,应该能通过阅读这些流程定义文件而了解实际的流程。

本指导资料目前有3部分:
1.
你的第一个工作流
2.
测试你的工作流
3.
更多的流程定义描述符概念

创建描述符  

 

首先,让我们来定义工作流。你可以使用任何名字来命名工作流。一个工作流对应一个XML格式的定义文件。让我们来开始新建一个“myworkflow.xml”的文件,这是样板文件:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE workflow PUBLIC

"-//dotnettools.org//DTD Workflow 2.8//EN"

"http://www.dotnettools.org/workflow/workflow_2_8.dtd">

<workflow>

<initial-actions>

...

</initial-actions>

<steps>

...

</steps>

</workflow>


首先是标准的XML头部,要注意的是Workflow将会通过这些指定的DTD来验证XML内容的合法性。你可以使用绝大多数的XML编辑工具来编辑它,并且可以highlight相应的错误。

步骤和动作  

 

接下来我们来定义初始化动作和步骤。首先需要理解的Workflow重要概念是steps (步骤) actions (动作)。一个步骤是工作流所处的位置,比如一个简单的工作流过程,它可能从一个步骤流转到另外一个步骤(或者有时候还是停留在一样的步骤)。举例来说,一个文档管理系统的流程,它的步骤名称可能有“First Draft - 草案初稿“Edit Stage -编辑阶段“At publisher - 出版商等。

动作指定了可能发生在步骤内的转变,通常会导致步骤的变更。在我们的文件管理系统中,在草案初稿这个步骤可能有“start first draft - 开始草案初稿“complete first draft - 完成草案初稿这样2个动作。
简单的说,步骤是在哪里,动作是可以去哪里

初始化步骤是一种特殊类型的步骤,它用来启动工作流。在一个工作流程开始前,它是没有状态,不处在任何一个步骤,用户必须采取某些动作才能开始这个流程。这些特殊步骤被定义在 <initial-actions>
在我们的例子里面,假定只有一个简单的初始化步骤:“Start Workflow”,它的定义在里面<initial-actions>

<action id="1" name="Start Workflow">

<results>

<unconditional-result old-status="Finished" status="Queued" step="1"/>

</results>

</action>


这个动作是最简单的类型,只是简单地指明了下一个我们要去的步骤和状态。

工作流状态  

 

工作流状态是一个用来描述工作流程中具体步骤状态的字符串。在我们的文档管理系统中,在草案初稿这个步骤可能有2个不同的状态:“Underway - 进行中“Queued - 等候处理中

我们使用“Queued”指明这个条目已经被排入“First Draft”步骤的队列。比如说某人请求编写某篇文档,但是还没有指定作者,那么这个文档在“First Draft”步骤的状态就是“Queued”“Underway”状态被用来指明一个作者已经挑选了一篇文档开始撰写,而且可能正在锁定这篇文档。

第一个步骤 

 

让我们来看第一个步骤是怎样被定义在<steps>元素中的。我们有2个动作:第一个动作是保持当前步骤不变,只是改变了状态到“Underway”,第二个动作是移动到工作流的下一步骤。我们来添加如下的内容到<steps>元素:

<step id="1" name="First Draft">

<actions>

<action id="2" name="Start First Draft">

<results>

<unconditional-result old-status="Finished" status="Underway" step="1"/>

</results>

</action>

<action id="3" name="Finish First Draft">

<results>

<unconditional-result old-status="Finished" status="Queued" step="2"/>

</results>

</action>

</actions>

</step>

<step id="2" name="finished" />


这样我们就定义了2个动作,old-status属性是用来指明当前步骤完成以后的状态是什么,在大多数的应用中,通常用"Finished"表示。

上面定义的这2个动作是没有任何限制的。比如,一个用户可以调用action 2而不用先调用action 1。很明显的,我们如果没有开始撰写草稿,是不可能去完成一个草稿的。同样的,上面的定义也允许你开始撰写草稿多次,这也是毫无意义的。我们也没有做任何的处理去限制其他用户完成别人的草稿。这些都应该需要想办法避免。
让我们来一次解决这些问题。首先,我们需要指定只有工作流的状态为“Queued”的时候,一个caller (调用者)才能开始撰写草稿的动作。这样就可以阻止其他用户多次调用开始撰写草稿的动作。我们需要指定动作的约束,约束是由Condition(条件)组成。

条件 

 

Workflow 有很多有用的内置条件可以使用。在此相关的条件是“StatusCondition - 状态条件 条件也可以接受参数,参数的名称通常被定义在docs里。在这个例子里面,状态条件接受一个名为“status”的参数,指明了需要检查的状态条件。我们可以从下面的xml定义里面清楚的理解:

<action id="2" name="Start First Draft">

<restrict-to>

<conditions>

<condition type="type">

<arg name="type.name">

DotNetTools.Workflow.Util.StatusCondition,DotNetTools.Workflow

</arg>

<arg name="status">Queued</arg>

</condition>

</conditions>

</restrict-to>

<results>

<unconditional-result old-status="Finished" status="Underway" step="1"/>

</results>

</action>


希望对于条件的理解现在已经清楚了。上面的条件定义保证了动作1只能在当前状态为“Queued”的时候才能被调用,也就是说在初始化动作被调用以后。

posted on 2006-07-17 20:43  榻榻米  阅读(2770)  评论(0)    收藏  举报