Windows Workflow Foundation 2 规则引擎简介

转载于:MSDN

http://www.microsoft.com/china/MSDN/library/Windev/WindowsVista/intWF_FndRlsEng.mspx?mfr=true

摘要:本文概述 Windows Workflow Foundation (WF) 中规则引擎的功能。本文描述如何在 WF 中使用条件和 RuleSet,并讨论规则集合的行为(包括,正向链接和跟踪与追踪)。

注 本文基于 Windows Workflow Foundation Beta 2 撰写,将来可能需要对本文进行修改以适用于 Windows Workflow Foundation 更新的版本。

*
本页内容
简介 简介
Windows Workflow Foundation 中规则的概述 Windows Workflow Foundation 中规则的概述
规则计算 规则计算
正向链接 正向链接
正向链接控件 正向链接控件
附加的建模讨论 附加的建模讨论
跟踪与追踪 跟踪与追踪
小结 小结
获得更多信息 获得更多信息

简介

在 Windows Workflow Foundation (WF) 的可用性方面,Microsoft 正在为 WinFX 开发人员平台引入新的规则功能。这些功能从驱动活动执行行为的简单条件一直扩展到由一个功能齐全的正向链规则引擎执行的复杂 RuleSet。

规则的功能允许在整个业务流程范围内对一个应用程序逻辑的各单元进行声明性建模。规则引擎技术的示例方案包括定单确认、价格计算、促销执行、异常处理管理,以及索赔理算和管理。

开发该技术的一个主要目的是提供一个真正集成的工作流和规则体验。在整个行业内,规则和工作流已代表性地成为相当独特的技术,通常由不同供应商提供。第三方规则引擎通常由工作流和业务流程管理(Business Process Management,BPM)提供商嵌入和集成,但是开发人员和管理体验显然不是一种平滑的体验。

就 WF 而言,Microsoft 已经非常重视在工作流和规则建模之间提供一种平滑的开发人员体验,从而使开发人员可以轻松地在其工作流的任意位置合并规则。开发人员能够决定是否对他们在工作流模型、规则或代码中的逻辑进行建模,而不必担心这些决定的集成含义。然而,该目标已经实现,并未丧失在工作流范围外执行规则的能力。

另一个主要目的一直是提供一个简单易懂的模型,供开发人员在定义规则时使用。迄今为止,规则技术一直是一种称心如意的技术,由一些非常专业的规则专业人员使用。尽管工具使用方面的改进已经扩大了使用规则人员的范围,但模型常常要求用户十分精通基础引擎的实现机制。向平台提供规则功能的过程中,我们选择了这样一个模型:它将由广泛的 .NET 开发人员社区轻松使用,最终非开发人员也能使用它。虽然始终会有某一级别领域的专业知识(对于任何技术而言),但我们的目标是让所有 .NET 开发人员都能够快速掌握该规则模型并能够将它轻松地合并到他们的应用程序中。

除了提供易用的模型外,WF 还提供一个强大的计算引擎来支持复杂的规则方案,要求正向链接计算和精确计算控制。该引擎通过一种提供大量扩展性点的方式提供,从而使开发人员能够在我们的平台上进行构建并提供规则功能以支持广泛的方案。

本文从技术角度介绍 WF 中提供的规则功能,并且概述可用的功能及其用法。本文结尾处提供一个其他资源的列表,可通过该列表了解 WF 中的规则功能。

Windows Workflow Foundation 中规则的概述

在 WF 中,通过两种主要方式公开规则技术:一种是作为活动上的条件,另一种是作为策略活动中的正向链接 RuleSet。正向链接将在本文稍后部分论述;简言之,它指一个规则的动作导致重新计算其他有依赖关系的规则的能力。

活动条件

条件由 WF 提供的以下四种活动使用:

IfElseBranch

While

Replicator

ConditionedActivityGroup (CAG)

条件用于驱动这些活动的执行行为,例如,决定是否要执行给定的 IfElseBranch。条件可以指定为 CodeConditions(这将在代码旁边出现一个配置好的处理程序)或 RuleConditionReferenceRuleConditionReference 将指向 .rules 文件中的 RuleCondition 定义,该文件与工作流项目中的工作流相关联。Visual Studio 中的操作如图 1 所示。


图 1. WF 规则条件创作

添加规则条件

向 IfElse 活动内部包含的 IfElseBranch 活动添加一个规则条件,步骤如下:

如果选择一个带条件的活动(如显示的 IfElseBranch 活动),Properties 网格中会显示 Condition 属性。

Condition 属性的下拉列表允许用户选择 CodeConditionRuleConditionReference

如果选择 RuleConditionReference,则可以展开 Condition 属性,看到 ConditionNameExpression 属性。

提供条件名后,选择椭圆形框中的 Expression 属性,启动 Rule Condition Editor。该编辑器允许开发人员以文本格式键入条件,并具有类似智能感知的支持。键入的文本解析为 RuleCondition 相关联的对象模型表示形式。

选择 OK 后,RuleCondition 定义序列化为一个 .rules 文件,然后该文件添加到项目中。

要引用工作流上的字段或属性,可在该编辑器中键入 this.。键入句点 (.) 后,出现一个类似智能感知的菜单,您可从中选择工作流上的成员(也可以直接键入成员)。还可进行嵌套调用,例如 this.order.Total。编写代码时,通过键入类名后面跟方法名,可以在引用的类型上调用静态方法。

表达式中支持下列关系操作符:

等号("=="或"=")

大于号(">")

大于等于号(">=")

小于号("<")

小于等于号("<=")

此外,您可以使用下列算术操作符:

加号("+")

减号("-")

乘号("*")

除号("/")

取模("MOD")

可以使用下列操作符合并/否定表达式:

与("AND"或"&&")

或("OR"或"||")

非("NOT"或"!")

按位与("&")

按位或("|")

开发人员使用规则条件 (Rule Condition) 取代代码条件 (Code Condition) 的主要原因是,规则条件成为模型的组成部分并且可在运行时在正在执行的工作流实例上动态更新。规则条件的第二个优势是,作为模型的组成部分,更复杂的工具可构建到模型的顶层,从而提供额外的创作体验、依赖性管理、交叉条件分析等。

策略活动

策略活动封装 RuleSet 的定义和执行。RuleSet 是一个带有一组执行语义的规则集合。而规则是对工作流成员进行操作的 If-Then-Else 表达式。实际操作如图 2 所示,类似于规则条件中所示。


图 2. WF RuleSet 创作

添加策略活动

要为策略活动配置一个规则集,请执行以下步骤:

将策略活动从工具箱拖到工作流设计器上。

RuleSetReference 中,为 RuleSet 指定一个名称。

选择椭圆形中的 RuleSet Definition 字段,启动 Rule Set Editor。

该编辑器在列表框中显示规则的集合。

选择一个给定的规则可以显示其 Condition、Then 操作、Else 操作以及一组其他属性。

和 Rule Condition Editor 中一样,Condition、Then 操作和 Else 操作均以文本方式输入,然后解析为相关联的对象模型表示形式;根据工作流上的成员生成规则。

选择 OK,将 RuleSet 序列化到与工作流关联的 .rules 文件。

注意,选择椭圆形中的 RuleSetReference 属性将启动编辑器,从而使用户能选择一个现有的 RuleSet 或添加/重命名/删除 RuleSet,如图 3 所示。


图 3. WF RuleSet 浏览器

规则计算

RuleSet 中的每个规则都有一个优先级值,默认值为 0。可将 RuleSet 中的规则看作一个按优先级值排列的有序集合。WF 规则计算器分别计算规则,根据规则的条件计算结果执行规则的操作。

计算机制在概念上可以用以下过程描述:

首先,列出活动的规则。

找到优先级最高的规则。

计算规则并根据需要执行其 Then/Else 操作。

如果一个规则的操作更新了列表中前面的某条规则(该规则具有较高的优先级)使用的字段/属性,则重新计算前面这条规则并根据需要执行其操作。注意,只有那些具有特定依赖性的规则才需要重新计算。

继续该过程,直至 RuleSet 中的所有规则均已计算完毕。

我们来看一个简单的示例。假定有以下 RuleSet,其中 AB 等代表工作流上的数据。

Rule4 (Priority = 4)

IF A = 15
THEN B = 5

Rule3 (P=3)

IF C = 5
THEN B = 10

Rule2 (P=2)

IF D = 2
THEN A = 15

Rule1 (P=1)

IF B = 5
THEN E = 7

假定有以下输入数据:

A = 0

B = 0

C = 5

D = 2

E = 0

计算将按以下方式进行:

计算 Rule4;其计算结果为 false,由于 Rule4 没有 Else 操作,因此不执行任何操作。

Rule3 的计算结果为 true,执行其操作,设置 B = 10。Rule4 不依赖于 B 的值,因此进行 Rule2 的计算。

Rule2 的计算结果为 true,执行其操作,设置 A = 15

由于 Rule4 在其条件中使用 A 的值,因此要重新计算 Rule4。Rule4 的计算结果为 true,执行其操作,设置 B = 5;由于 Rule3 和 Rule2 的条件不依赖 A 的值,因此它们不用重新计算。由于前面的值都不依赖于 B 的值,因此进行 Rule1 的计算。

Rule1 的计算结果为 true,执行其操作,设置 E = 7

结果数据集应该如下所示:

A = 15

B = 5

C = 5

D = 2

E = 7

正向链接

如以前所述,链接基于规则中已识别的依赖项;更具体地说,就是一个规则的操作和其他规则的条件之间的依赖项。这些依赖项可通过以下方式识别或声明:

隐式

基于属性

显式

隐式

隐式依赖项由引擎自动识别。第一次执行某个 RuleSet 时,分析每个规则以评估它读入条件中并写入操作中的字段/属性。逐步执行条件中的表达式以及操作中的语句,即可完成该操作。例如,假定以下规则。

Rule 1

IF this.subtotal > 10000
THEN this.discount = .05

Rule 2

IF this.discount > 0
THEN this.total = (1-this.discount) * this.subtotal

引擎将计算规则,并识别 Rule 1 是否读取 subtotal 字段并将它们写入 discount 字段。Rule 2 读取 discount 和 subtotal 字段,然后将它们写入 total 字段。因此,Rule 2 在 Rule 1 上有一个依赖项;结果是引擎将确保每次 Rule 1 执行其 Then 操作时,都会对 Rule 2 进行计算/重新计算。

注意,依赖项在叶节点级别进行识别。看看以下 RuleSet。

Rule 1

IF this.order.Subtotal > 10000
THEN this.order.Discount= .05

Rule 2

IF this.order.Discount > 0
THEN this.order.Total = (1-this.order.Discount) * this.order.Subtotal

Rule 3

IF this.order.CustomerType = "Residential"
THEN ...

依赖项仍将在 Rule 1 和 Rule 2 之间进行识别。然而,Rule 3 在 Rule 1 和 Rule 2 上没有依赖项,因此它不更新 CustomerType 属性。换言之,依赖项在 CustomerType 属性级别进行识别,而不是由 Order 对象本身识别。

通过隐式链接,WF 为用户提供大多数必要的链接,因此用户不必显式对更新进行建模,实际上在大多数实例中,用户可以不必了解链接或对链接的需求。我们希望这将使大多数用户更直观地了解复杂 RuleSet 的建模,让链接的概念成为一种强大的(但主要是隐含的)引擎功能。然而,其他两种驱动链接的机制(基于属性和显式)是为更复杂、更特定的方案而提供的。

基于属性

对于规则中的方法调用,明确地计算发生的读/写操作变得更难了。为了解决该问题,WF 提供了三个可应用于方法以指示其操作的属性:

RuleRead

RuleWrite

RuleInvoke

利用 RuleRead 特性化某个方法可以指示该方法读取指示的属性。同样,RuleWrite 属性可用于指示某个方法更新给定的字段或属性。假定我们在隐式部分中的前两个规则进行如下重写。

Rule 1

IF this.subtotal > 10000
THEN this.SetDiscount(.05)

Rule 2

IF this.discount > 0
THEN this.total = (1-this.discount) * this.subtotal

然后,SetDiscount 方法的特性化如下所示,这将允许引擎识别 Rule 2 由于使用 discount 字段而依赖于 Rule 1。

[RuleWrite("discount")] 
void SetDiscount(double requestedDiscount)
{
     ...//some code that updates the discount field
}

RuleInvoke 属性可用于指示由于链接的方法调用而产生的依赖项。例如,假定对规则和方法进行以下修改。

Rule 1

IF this.subtotal > 10000
THEN this.SetDiscountWrapper(.05)

Rule 2

IF this.discount > 0
THEN this.total = (1-this.discount) * this.subtotal
[RuleInvoke("SetDiscount")]
void SetDiscountWrapper(double requestedDiscount)
{
     ...
     SetDiscount(requestedDiscount);
     ...
}

[RuleWrite("discount")] 
void SetDiscount(double requestedDiscount)
{
}

Rule 2 的条件调用 SetDiscountWrapperSetDiscountWrapper 又调用 SetDiscount,后者写入 discount 字段。RuleInvoke 属性允许引擎声明和检测该间接写操作。

识别出属性路径中引用的字段或属性指的是与方法相同的类上的字段或属性很重要,这不一定是传递给 RuleSet 用于执行的根对象。例如,您可以按如下所示特性化 Order 类。

public class Order
{
     private double discount;

     public double Discount
     {
     get { return discount;}
     set { discount = value;}
     }

     [RuleWrite("Discount")] 
     void CalculateDiscount(double requestedDiscount, double weighting)
     {
...//some code that updates the discount field
     }
}

然后,您可以按如下方式在工作流中使用该类的一个实例。

public class Workflow1 :  SequentialWorkflowActivity
{
     private Order discount;

     ...
}

然后,执行 Rule 2 将导致重新计算 Rule 1。

Rule 1

IF this.order.Discount > 5
THEN ...

Rule 2

IF ...
THEN this.order.CalculateDiscount( 5.0, .7)

属性使用过程中一些需要注意的内容:

指向 Owner 类上的字段/属性的属性,而不是一个方法调用的参数。

在规则属性中也可以使用通配符。例如,RuleWrite("order/*") 可用于指示"order"字段引用的对象上的所有字段由方法(本例中,该方法位于工作流本身上,而非 Order 类上)进行修改。然而通配符只能用于路径的结尾处;像 RuleWrite("*/Discount") 这样的属性是无效的。

RuleWrite("order") 这样的属性可与引用类型一起用来指示引用已更改,例如,指示变量现在指向另一个 Order 实例。所有使用变量上的一个字段/属性的规则将被认为是紧缩式的,除了测试实例引用本身的所有规则之外,例如 IF this.order == this.order2

如果没有指定方法属性,默认行为是假定某个方法调用读取目标对象(在该对象上调用方法)上的所有字段/属性,但不写入这些字段/属性。此外,假定方法读取传递给它的参数,但不写入这些参数。假定 Outref 参数在规则操作中使用时被写入。

显式

最后一种指示字段/属性依赖项的机制是使用 Update 语句。Update 语句的参数为字符串(表示到字段或属性的路径)或表达式(表示字段/属性访问)。例如,可在 RuleSet 编辑器中键入以下任一语句在工作流上的 Customer 实例的 Name 属性上创建一条 Update 语句。

Update("this/customer/Name") 

Update(this.customer.Name)

Update 语句指示规则写入到指示的字段/属性。产生的结果与规则中的一组直接字段/属性相同,或与对字段/属性调用具有 RuleWrite 属性的方法相同。

Update 命令也支持使用通配符。例如,可以向规则添加以下 Update 命令。

Update("this/customer/*")

这将导致重新计算任何在其条件中使用 Customer 实例上的任何属性的规则。换言之,将重新计算以下两个规则。

IF this.customer.ZipCode == 98052
THEN ...

IF this.customer.CreditScore < 600
THEN ...

通常,大多数情况下都不希望用户需要对显式 Update 语句进行建模。大多数情况下,隐式链接应该提供所需的依赖项分析和链接行为。方法的特性化应该支持大多数流行的方案,在这些方案中,隐式链接无法识别依赖项。通常,与使用 Update 语句相比,方法的特性化是用于指示依赖项的首选方法,这是因为依赖项能够在方法上识别一次,并且可以跨使用该方法的多个不同规则使用。此外,在规则编写器和方法执行器中方法的属性设置是不同个体(或者说是在不同时间使用)的情况下,方法的特性化允许方法书写器(它最了解代码)识别方法的依赖项。

但存在一些这样的情况:Update 语句将作为合适的解决方案,例如,当字段/属性传递给类的一个方法时,工作流书写器不能控制该类因此也无法对其进行特性化,这种情况如以下代码所示。

IF ...
THEN this.customer.UpdateCreditScore(this.currentCreditScore)
     Update(this.currentCreditScore)

正向链接控件

正向链接是一个非常强大的概念,它使原子则规则可以组装到 RuleSet,而无需定义甚至无需了解规则中依赖项的概念。

然而,在某些情况下,规则书写器也许希望能够对链接行为进行更多的控制,特别是希望能限制链接发生的行为。这使规则模块能够:

限制规则的重复执行,这可能会导致错误的结果。

提高性能。

预防失控的循环。

通过以下两个属性,有助于在 WF 规则中使用该级别的控件:

RuleSet 上的Chaining Behavior 属性。

每个规则上的 Reevaluation Behavior 属性。

这两个值均可在 RuleSet Editor 中设置。

Chaining Behavior 属性

RuleSet 上的 Chaining Behavior 属性有三个可能的值:

Full Chaining

Explicit Chaining

Sequential

Full Chaining 是默认选项,它提供目前为止所描述的行为。Explicit Chaining 选项关闭隐式链接和基于属性的链接,指示链接仅对显式的 Update 语句发生。这使规则书写器能完全控制哪些规则导致重新计算。通常,该选项用于以下两种情况:避免循环依赖项(导致过多的甚至失控的规则重新执行),或提高性能(通过消除提供 RuleSet 的功能完整性所不需要的多余的规则重新计算来实现)。

最后一个选项是 Sequential。该选项将导致引擎以严格的线性方式计算规则。每个规则都将按优先级顺序计算一次仅一次。优先级较高的规则可以影响优先级较低的规则,由于没有链接,因此优先级较低的规则不会影响优先级较高的规则。因此,该选项可以与显式优先级分配一起使用,除非规则中不存在依赖项。

Reevaluation Behavior 属性

规则上的 Reevaluation Behavior 有两个可能的值:

Always

Never

Always 是默认选项,它提供前面讨论过的行为,即将始终根据因其他规则的操作导致的链接对规则进行重新计算。顾名思义,Never 关闭该重新计算。该规则将计算一次,但如果它以前未执行任何操作,则不进行重新计算。换言之,如果规则之前已进行过计算,结果执行了其 ThenElse 操作,则不对它进行重新计算。然而,执行 ThenElse 操作中的空操作集合不会将一个规则标记为已执行。

通常,该属性将在规则级别使用,以防止因规则在它自己的操作上或其他规则上具有依赖项而导致的无限循环。例如,下面的规则会创建自己的无限循环,无需重新计算来实现规则的功能需求。

IF this.shippingCharge < 2.5 AND this.orderValue > 100
THEN this.shippingCharge = 0

或者,如果一定要重新计算规则(但仅当 OrderValue 字段更改时),则用户可以设置 RuleSet 上的链接行为仅在显式的 Update 语句上链接(然后将这些 Update 语句添加到相关的规则操作)。当然,用户可能已经向该规则附加了一个额外的谓词,该谓词检查 ShippingCost 的值尚未为 0,但链接控件不需要用户根据计算的详细信息(与他们的业务需求相反)来定义他们的规则。

Halt 函数

作为最后一个控件,Halt 函数可以作为一个规则操作添加(只需将"Halt"键入编辑器中的 ThenElse 操作框中)。这将立即停止 RuleSet 执行并将控件返回给调用代码。当然,使用该函数时不必局限于链接控件方案。例如,具有特定功能目标的 RuleSet 只要达到了目标,就可以使用 Halt 函数简化执行。

附加的建模讨论

基于优先级的执行

如同前面部分中提到的那样,如果用户希望 RuleSet 或该 RuleSet 中规则子集按特定顺序执行,他们可使用规则上的优先级字段精确定义该顺序。这样做通常不需要进行链接,用户甚至可以关闭这些方案中的链接。我们已经发现,许多情况下只需提供显式的执行顺序即可满足规则的依赖项。

然而,注意下面这一点很重要:WF 中的正向执行机制为用户提供了定义执行顺序的能力,但并不需要用户这样做。在大多数情况下,正向链接行为无需分配规则优先级即可得到正确的 RuleSet 结果,因为关系是通过引擎自动管理的,以确保满足规则的依赖项。

看看下面的规则。

Rule 1

IF this.Weather.Temperature < 50
THEN this.Drink.Style = "Latte"

Rule 2

IF this.Drink.Style == "Latte"
THEN this.Snack.Style = "Scone"
ELSE this.Snack.Style = "Muffin"

在 WF 中,您可以在 Rule 1 上提供一个较高的优先级,从而可以先执行它。这确保先设置 Drink.Style,然后再计算 Rule 2。

然而,要得到希望的结果,不需要设置顺序。假定先计算 Rule 2。在这种情况下,Drink.Style 可能为 null,也可能为其他样式。结果是 Snack.Style 设置为 Muffin。然而,在 Rule 1 执行并将 Drink.Style 发送到 Latte 之后,Rule 2 将重新计算并将 Snack.Style 设置为 Scone。基本上,用户可以选择指定序列,但在许多情况下并不需要这样做。

集合处理

在某些情况下,您可能需要根据集合中所有单独的项计算规则。可以通过多种方式迭代集合,但一种方式是使用如下所示的规则模式:

Rule 1 (Priority = 2)

//always execute this rule once to create the enumerator
IF 1==1 
THEN this.enumerator = this.myCollection.GetEnumerator()

Rule 2 (Priority = 1)

IF this.enumerator.MoveNext()
THEN this.currentInstance = this.enumerator.Current

Rules 3-N (Priority = 0)

.... //additional rules written against this.currentInstance

Rule N+1 (Priority = -1)

// can be any condition as long as it is evaluated every time;
// this.currentInstance will be evaluated each time 
//this.currentInstance changes, whereas 
// "1==1" would only be evaluated once
IF this.currentInstance == this.currentInstance  
                                                                           
THEN ...
         Update("this/enumerator") //this will cause Rule 2 to be reevaluated
ELSE ...
          Update("this/enumerator")

跟踪与追踪

跟踪

RuleSet 执行时,跟踪事件发送到主机上配置好的跟踪服务,主机通过向其跟踪配置文件中添加 UserTrackPoint 对这些事件进行了注册。发送一个 RuleActionTrackingEvent,它提供计算的规则的名称,以及条件计算结果 (true/false)。有关示例,请参考 SDK 中的 RuleActionTrackingEvent 示例。

活动上规则条件的计算结果可以通过跟踪活动执行进行隐式跟踪。

追踪

通过将以下代码添加到应用程序配置文件,可以将额外的 RuleSet 计算信息发送到一个日志文件。

<configuration>
<system.diagnostics>
<switches>
<add name="Rules" value="Information"/>
</switches>
</system.diagnostics>
</configuration> 

以下信息将发送到日志文件:

条件依赖项信息:

示例: Rule "ReturnNumberOfStops" Condition dependency: "this/currentFlight/OutboundFlight/NumberOfStops/"

操作副作用信息:

示例: Rule "ReturnNumberOfStops" THEN side-effect: "this/currentFlight/Score/"

链接关系:

示例: Rule "ReturnNumberOfStops" THEN actions trigger rule "ApprovedFlights"

RuleSet 执行:

示例: Rules: "Executing RuleSet FlightRuleSet"

条件计算:

示例: Rules:Evaluating condition on rule "SetDefaultScore"

条件计算结果:

示例: Rules:Condition evaluated to True

操作执行:

示例: Rules:Evaluation THEN actions for rule "SetDefaultScore"

目前,所有追踪消息都在"Information"级别定义,因此您应该在配置文件中指定 Information 或 Verbose 的级别来查看规则追踪。

小结

WF 提供可通过许多不同方式使用的灵活的规则功能,从而支持广泛的方案。从简单的活动条件到复杂的正向链接 RuleSet,该技术使您能够将平滑地将规则集成到您的工作流中。另外,还可以在工作流外部使用规则引擎为任何 .NET 应用程序提供规则功能。

该功能集使新的开发人员可以轻松地将简单规则合并到工作流中,同时仍然提供丰富性和扩展性以支持更高级的 RuleSet 和应用程序方案。本文档结合下一部分中引用的资源应该有助于不熟悉 WF 规则的开发人员了解该技术,并快速高效地使它。

获得更多信息

MSDN Workflow 站点

提供大量文档,以及到网络广播和实验室的链接。

社区站点示例

External RuleSet Toolkit - 提供一个有关如何具体化工作流程序集的规则的示例。

RuleSet Analysis - 一个分析各规则之间以及规则与数据之间关系 RuleSet 的工具。

Rules in Excel - 提供一个有关如何使用独立的、工作流之外的规则的示例。还演示如何通过编程方式创建通过 Excel 中的决策表创作规则。

SDK 示例

IfElseWithRules - 说明 RuleCondition 在 IfElse 活动(位于 \Technologies\RulesAndConditions 中)上的使用。

DynamicUpdateChangingRules - 演示使用动态更新 API 以更改运行的工作流实例上 (\Technologies\RulesAndConditions) 的 RuleCondition。

SimplePolicy - 演示使用 API 定义一个简单的 RuleSet 和策略活动 (\Technologies\Activities\Policy)。

AdvancedPolicy - 定义一个更复杂的 RuleSet (\Technologies\Activities\Policy)。

RuleActionTrackingEventSample - 说明如何捕获跟踪提供程序 (\Technologies\Tracking) 中的规则计算结果。

MSDN Workflow 论坛

有关 WF 规则或 WF 的常规问题,请访问该论坛。

posted on 2006-05-16 20:40  周 金根  阅读(1068)  评论(0编辑  收藏  举报

导航