WF-Activity高级篇-Policy Activity
[ 2006-02-09 19:47:31 | Author: ccBoy ]
Policy
Policy Activity 封装了一个集成的的规则引擎,并且允许你在业务逻辑和应用中使用这些规则引擎。
一个Policy 是代表你定义一组类似的"If-Then-Else" 逻辑的规则并且将它组织在一个RuleSet中,然后你可以使用Policy Activity 来调用或执行这些规则引擎。这些规则很大程度上使用的是CodeDom类型,所以不像WF的其他 Activity ,Policy Activity很多时候不能直接使用(特别是不能在VS2005的工具箱),你需要从Policy Activity继承并且创建一个自定义的 Activity来使用Policy Activity和这些规则。
一般使用上,
第一个问题是CodeDom 和 RuleSetEditor 两种方式你更喜欢哪种。如果不是做练习,那么我更喜欢RuleSetEditor 的方式,因为Beta1的时候,没有RuleSetEditor (只有一个外置的小工具RuleSetEditor - 2005-09-12.exe),而Beta2这个工具内置进来了。你更多的时候是只能使用CodeDom,
第二,使用CodeDom的方式,会将Rule和你的Policy Activity 编译到一起成为一个二进制的格式,我不喜欢这种方式,使用RuleSetEditor会单独的生成一个后缀为.rules的XML文件,编译后和CodeDom的方式是一样的,我更喜欢这种分离的模式,而且你还可以使用程序序列化的方式来动态的序列化RuleSets,而后我会专门的讨论一些规则引擎的问题,因为WF的论坛上,提供了两个工具ExternalRuleSetToolkit 和RuleSetAnalyzer,而整个的规则引擎也是一个比较大的话题,值得一说。
Policy 其他的一些属性
1. Priorities
第一一个Rulesets中可以有多个相同的Rule,那么Priorities就非常有用了,第二,你可以需要一些Rule优先被执行,那么Priorities 也非常有用。显然高优先级的Rule会被先执行,其顺序是从高到低的执行,比如折扣那么高优先级的规则计算的折扣会覆盖低优先级规则计算的折扣,Priorities属性可以是正值也可以是负数,默认是0,如果所有的规则你都没有设置Priorities属性,那么默认都是0,则执行的顺序由WF引擎决定。
2.ReevaluationBehavior 属性
这个属性决定了每个Rule的IF条件被执行或评估的动作。一般有两个选项
Always-这个比较容易理解,这意味着,规则的条件总是要重新评估,如果满足则规则的Active会被执行。
Never-指条件满足,则规则的Active会被执行一次,但之后条件不会再被评估,规则的Active也不会执行。Never意味这规则的IF条件满足,规则的Active总会被执行一次。
3.Method Access
这个是指除了你可以在Rule中直接使用Policy Activity的属性外,你还通过定义一个方法-在这个方法中修改属性。然后再让规则引擎调用这个方法。比如有一个规则,客户的类型变化之后,客户的折扣比率会发送变化,那么客户的折扣比率可以是Policy Activity中的一个属性,你也可定义一个方法,在这个方法中,先计算汇率或其他运算然后在修改折扣比率,这时候使用调用一个方法比直接修改属性表示上更简单,而且如上面说的,你还可以进行一些运算、转换或其他的逻辑。这个方法可以是Policy Activity 中的方法,也可以是一个某个.NET Assembly 中的静态方法
因为这里是一个方法,所有这个方法可能是读这个属性,也可能是写这个属性。WF有两个属性 RuleReadAttribute, 和 RuleWriteAttribute 可以解决这个问题。还有一个属性RuleInvokeAttribute,表明一个规则条件的判断会调用一个方法。
RuleReadAttribute, 和 RuleWriteAttribute 是针对Rule的Action,RuleInvokeAttribute 则是针对Rule 的Condition
使用上非常简单,你需要定义一个Public的方法,然后上面使用这三个属性中的一个,比如
[RuleWrite("FieldXXXX")]
public void ModifyFieldXXXX()
{
This.FieldXXXX = 10;
}
后面我们讲到规则链的类型时候,还会提到这三个属性
4. Chaining
规则链和我们说的连锁反应非常相似,也就是说一个规则的变化可能触发规则引擎中其他的规则,像连锁反应一样,一个规则接着一个规则的触发。 比如
IF This.Field1 == 5 THEN This.Field2 = 10
IF This.Field2 == 10 THEN This.Field3 = 20
IF This.Field3 == 20 THEN This.Field4 = 30
WF提供反应链式(forward-chaining)的规则,这意味着你可以通过简单的方式定义“混杂”的Policy。
这个“混杂”的Policy意味着:
1. 规则间的依赖关系和顺序不是显示的定义的。
2. 已经执行或评估过的规则被确认需要重新评估或执行
这个好处是定义规则的Priorities属性所不能达到的。
WF Beta2支持三种类型的规则链:implicit, declarative, 和explicit.
Implicit 方式
这种类型和上面我们举例的情况是一样的,因为定义了三条规则,但我们没有显示的定义三个规则执行的顺序,当规则一执行之后,WF会自动的评估规则二,依次进行评估。
另外一种情况是这样的 IF TaxRate < 11 THEN TaxRate = 11 比如你设定了这样的一个规则,那么任何其它的规则只用修改了TaxRate的状态,那么这条规则都需要重新进行评估,如果条件符合,那么规则将会执行。
Declarative 方式
这种方式下主要某个条件满足后,不是直接修改属性,而是调用了一个方法,那么这个方法也可能修改某个属性,而激发连锁的规则条件评估
比如
IF This.Field1 == 5 THEN ModifyField2
IF This.Field2 == 10 THEN This.Field3 = 20
[RuleWrite("Field2")]
public void ModifyField2()
{
This.Field2 = 10;
}
RuleWrite (也就是上面我们提到的属性)标识该方法会修改Field2 属性,那么所有针对Field2的规则WF都会重新进行评估
Explicit 方式
这种方式非常简单,WF内置了一个语句-Update,通过这个方法你可以告诉WF,某个属性一定会被修改了,相关的规则可能需要重新评估
比如:
IF This.Field1 == 5 THEN ModifyField2(); Update("Field2")
IF This.Field2 == 10 THEN This.Field3 = 20
这个意味你告诉WF的规则引擎,Field2修改了相关的规则需要进行重新的评估
和Update语句还有一个Halt 语句,这个语句是一个类似Ctrl-C的中断命令,意味着告诉WF规则引擎,停止所有规则和该规则库的执行,立即返回控制到调用者。立即的意思意味着即使在Halt语句之前已经有Active定义或调度要执行,那么也将中断
Halt 语句对应WF的RuleHaltAction 类,Update 语句对应WF的 RuleUpdateAction 类。
了解了这三种类型,你就可以轻易的对应到RuleSet Editor中的 Chaining 选项
Sequential --表明是顺序的,也就是说不允许规则链,这个相当于 RuleChainingBehavior.None
Explicit Chaining-意味这你需要显式的规则链,这个相当于 RuleChainingBehavior.UpdateOnly
Full Chaining-意味完全支持规则链,也就是三种类型的规则链都支持。这个相当于 RuleChainingBehavior.Full
WF Beta1中每个Rule还有一个MaxExecutionCount ,但WF Beta2好像已经没有了,已经变成了RuleReevaluationBehavior,个人感觉这个没有MaxExecutionCount方便和直观。
5. 扩展和编程方式执行
这个主要是指你可能想让Policy Activity 在运行时执行一个的RuleSets,而这个RuleSets是分隔在一个我们上面讲到后缀是.rules的XML文件中的,抑或是External RuleSet Toolkit 提到的RuleSet Service,比如数据库中。那么Policy Activity 也是支持的。
编程方式执行主要是指使用WorkflowMarkupSerializer,可以将规则引擎序列化化到一个XML文件中或反序列一个RuleSet的XML文件到一个RuleSet对象,然后在Policy Activity 运行时进行调用
好了,上面就是WF Policy Activity 的描述,很多人问其WF的规则引擎在那里,我怎么没有看见,其实Policy Activity是规则引擎在WF中的一个展现或插件,如果你要在WF的工作流中使用WF内置的规则引擎,那么你第一个要想到的就是Policy Activity
Ver: 1.00
注意-文章原创作品。版权所有,不得擅自转载或以其它方式的传播
Comments Feed: http://www.dotnettools.org/Blog/feed.asp?q=comment&id=84
Policy Activity 封装了一个集成的的规则引擎,并且允许你在业务逻辑和应用中使用这些规则引擎。
一个Policy 是代表你定义一组类似的"If-Then-Else" 逻辑的规则并且将它组织在一个RuleSet中,然后你可以使用Policy Activity 来调用或执行这些规则引擎。这些规则很大程度上使用的是CodeDom类型,所以不像WF的其他 Activity ,Policy Activity很多时候不能直接使用(特别是不能在VS2005的工具箱),你需要从Policy Activity继承并且创建一个自定义的 Activity来使用Policy Activity和这些规则。
一般使用上,
- 1. 先定义一个从Policy Activity继承来的自定义Activity
- 2. 定义一些数据字段为这个Activity的属性
- 3. 然为这个Activity定义一个System.Workflow.Activities.Rules.RuleSet , 可以使用CodeDom 定义一个或多个Rule,加入到这个RuleSet 中。 一个Rule包括一个条件以及一个多多个Active,一般条件相当于上面说的IF,另外的Active则相当于Then和Else的场景。最简单的方法,也可以使用Role Editor 来完成这些。
- 4. 每个Policy Activity都有一个RuleSetReference 属性,定义完RuleSet 之后,可在VS界面中设置该属性,代码方式下则需要将这个RuleSet封装到一个RuleDefinitions 对象中,然后设置Policy Activity的RuleDefinitions.RuleDefinitionsProperty 为封装的RuleDefinitions对象
第一个问题是CodeDom 和 RuleSetEditor 两种方式你更喜欢哪种。如果不是做练习,那么我更喜欢RuleSetEditor 的方式,因为Beta1的时候,没有RuleSetEditor (只有一个外置的小工具RuleSetEditor - 2005-09-12.exe),而Beta2这个工具内置进来了。你更多的时候是只能使用CodeDom,
第二,使用CodeDom的方式,会将Rule和你的Policy Activity 编译到一起成为一个二进制的格式,我不喜欢这种方式,使用RuleSetEditor会单独的生成一个后缀为.rules的XML文件,编译后和CodeDom的方式是一样的,我更喜欢这种分离的模式,而且你还可以使用程序序列化的方式来动态的序列化RuleSets,而后我会专门的讨论一些规则引擎的问题,因为WF的论坛上,提供了两个工具ExternalRuleSetToolkit 和RuleSetAnalyzer,而整个的规则引擎也是一个比较大的话题,值得一说。
Policy 其他的一些属性
1. Priorities
第一一个Rulesets中可以有多个相同的Rule,那么Priorities就非常有用了,第二,你可以需要一些Rule优先被执行,那么Priorities 也非常有用。显然高优先级的Rule会被先执行,其顺序是从高到低的执行,比如折扣那么高优先级的规则计算的折扣会覆盖低优先级规则计算的折扣,Priorities属性可以是正值也可以是负数,默认是0,如果所有的规则你都没有设置Priorities属性,那么默认都是0,则执行的顺序由WF引擎决定。
2.ReevaluationBehavior 属性
这个属性决定了每个Rule的IF条件被执行或评估的动作。一般有两个选项
Always-这个比较容易理解,这意味着,规则的条件总是要重新评估,如果满足则规则的Active会被执行。
Never-指条件满足,则规则的Active会被执行一次,但之后条件不会再被评估,规则的Active也不会执行。Never意味这规则的IF条件满足,规则的Active总会被执行一次。
3.Method Access
这个是指除了你可以在Rule中直接使用Policy Activity的属性外,你还通过定义一个方法-在这个方法中修改属性。然后再让规则引擎调用这个方法。比如有一个规则,客户的类型变化之后,客户的折扣比率会发送变化,那么客户的折扣比率可以是Policy Activity中的一个属性,你也可定义一个方法,在这个方法中,先计算汇率或其他运算然后在修改折扣比率,这时候使用调用一个方法比直接修改属性表示上更简单,而且如上面说的,你还可以进行一些运算、转换或其他的逻辑。这个方法可以是Policy Activity 中的方法,也可以是一个某个.NET Assembly 中的静态方法
因为这里是一个方法,所有这个方法可能是读这个属性,也可能是写这个属性。WF有两个属性 RuleReadAttribute, 和 RuleWriteAttribute 可以解决这个问题。还有一个属性RuleInvokeAttribute,表明一个规则条件的判断会调用一个方法。
RuleReadAttribute, 和 RuleWriteAttribute 是针对Rule的Action,RuleInvokeAttribute 则是针对Rule 的Condition
使用上非常简单,你需要定义一个Public的方法,然后上面使用这三个属性中的一个,比如
[RuleWrite("FieldXXXX")]
public void ModifyFieldXXXX()
{
This.FieldXXXX = 10;
}
后面我们讲到规则链的类型时候,还会提到这三个属性
4. Chaining
规则链和我们说的连锁反应非常相似,也就是说一个规则的变化可能触发规则引擎中其他的规则,像连锁反应一样,一个规则接着一个规则的触发。 比如
IF This.Field1 == 5 THEN This.Field2 = 10
IF This.Field2 == 10 THEN This.Field3 = 20
IF This.Field3 == 20 THEN This.Field4 = 30
WF提供反应链式(forward-chaining)的规则,这意味着你可以通过简单的方式定义“混杂”的Policy。
这个“混杂”的Policy意味着:
1. 规则间的依赖关系和顺序不是显示的定义的。
2. 已经执行或评估过的规则被确认需要重新评估或执行
这个好处是定义规则的Priorities属性所不能达到的。
WF Beta2支持三种类型的规则链:implicit, declarative, 和explicit.
Implicit 方式
这种类型和上面我们举例的情况是一样的,因为定义了三条规则,但我们没有显示的定义三个规则执行的顺序,当规则一执行之后,WF会自动的评估规则二,依次进行评估。
另外一种情况是这样的 IF TaxRate < 11 THEN TaxRate = 11 比如你设定了这样的一个规则,那么任何其它的规则只用修改了TaxRate的状态,那么这条规则都需要重新进行评估,如果条件符合,那么规则将会执行。
Declarative 方式
这种方式下主要某个条件满足后,不是直接修改属性,而是调用了一个方法,那么这个方法也可能修改某个属性,而激发连锁的规则条件评估
比如
IF This.Field1 == 5 THEN ModifyField2
IF This.Field2 == 10 THEN This.Field3 = 20
[RuleWrite("Field2")]
public void ModifyField2()
{
This.Field2 = 10;
}
RuleWrite (也就是上面我们提到的属性)标识该方法会修改Field2 属性,那么所有针对Field2的规则WF都会重新进行评估
Explicit 方式
这种方式非常简单,WF内置了一个语句-Update,通过这个方法你可以告诉WF,某个属性一定会被修改了,相关的规则可能需要重新评估
比如:
IF This.Field1 == 5 THEN ModifyField2(); Update("Field2")
IF This.Field2 == 10 THEN This.Field3 = 20
这个意味你告诉WF的规则引擎,Field2修改了相关的规则需要进行重新的评估
和Update语句还有一个Halt 语句,这个语句是一个类似Ctrl-C的中断命令,意味着告诉WF规则引擎,停止所有规则和该规则库的执行,立即返回控制到调用者。立即的意思意味着即使在Halt语句之前已经有Active定义或调度要执行,那么也将中断
Halt 语句对应WF的RuleHaltAction 类,Update 语句对应WF的 RuleUpdateAction 类。
了解了这三种类型,你就可以轻易的对应到RuleSet Editor中的 Chaining 选项
Sequential --表明是顺序的,也就是说不允许规则链,这个相当于 RuleChainingBehavior.None
Explicit Chaining-意味这你需要显式的规则链,这个相当于 RuleChainingBehavior.UpdateOnly
Full Chaining-意味完全支持规则链,也就是三种类型的规则链都支持。这个相当于 RuleChainingBehavior.Full
WF Beta1中每个Rule还有一个MaxExecutionCount ,但WF Beta2好像已经没有了,已经变成了RuleReevaluationBehavior,个人感觉这个没有MaxExecutionCount方便和直观。
5. 扩展和编程方式执行
这个主要是指你可能想让Policy Activity 在运行时执行一个的RuleSets,而这个RuleSets是分隔在一个我们上面讲到后缀是.rules的XML文件中的,抑或是External RuleSet Toolkit 提到的RuleSet Service,比如数据库中。那么Policy Activity 也是支持的。
编程方式执行主要是指使用WorkflowMarkupSerializer,可以将规则引擎序列化化到一个XML文件中或反序列一个RuleSet的XML文件到一个RuleSet对象,然后在Policy Activity 运行时进行调用
好了,上面就是WF Policy Activity 的描述,很多人问其WF的规则引擎在那里,我怎么没有看见,其实Policy Activity是规则引擎在WF中的一个展现或插件,如果你要在WF的工作流中使用WF内置的规则引擎,那么你第一个要想到的就是Policy Activity
Ver: 1.00
注意-文章原创作品。版权所有,不得擅自转载或以其它方式的传播
Comments Feed: http://www.dotnettools.org/Blog/feed.asp?q=comment&id=84
There is no comment on this article.
You can't post comment on this article.








