WF中提供了非常灵活的规则引擎,主要表现为两种形式即活动上的条件和规则集RuleSet。本文我们来详细说说活动上的条件。
WF本身提供的活动中有以下几个活动可以使用条件:
-
IfElseBranchActivity,它包含在 IfElseActivity 活动中,在具有的条件计算结果为 True 时执行。
-
WhileActivity 只要活动的条件计算结果为true,它就会连续执行所包含的任何活动。每次循环完成时重新计算该条件。
-
ConditionedActivityGroup 连续执行所包含的任何活动,直到其条件计算结果为 true。 ConditionedActivityGroup 中的每个单个活动都具有 When 条件。 仅当 When 条件计算结果为 true 时才执行各个活动。
-
ReplicatorActivity 在其 UntilCondition 属性计算结果为 true 时完成执行。
我们可以在自己创建的自定义活动中使用条件。我们有两种方式来设置条件,一种是声明行规则条件,将被序列化到.rules文件中,另一种是代码条件,我们通过自己编写程序来设置条件,最后使用Result 属性返回。如下图所示:
表达式中支持下列关系操作符:
等号("=="或"=")
大于号(">")
大于等于号(">=")
小于号("<")
小于等于号("<=")
可以使用下列算术操作符:
加号("+")
减号("-")
乘号("*")
除号("/")
取模("MOD")
可以使用下列操作符合并/否定表达式:
与("AND"或"&&")
或("OR"或"||")
非("NOT"或"!")
按位与("&")
按位或("|")
使用代码方式比较简单,我们只要在系统生成的事件处理函数中写我们的逻辑代码就可以,最后设置参数ConditionalEventArgs的Result属性为返回值。条件被编译并成为程序集的一部分。 运行时引擎执行该方法并使用 Result 属性作为条件计算的结果。
我们来看看当我们使用规则条件时WF为我们做了什么?他会将规则条件序列化到.rules文件中,然后创建新的 RuleConditionReference。将ConditionName 属性设置为等于 .rules 文件中RuleExpressionCondition 元素的Name 属性值。最后在将Condition 属性设置为刚刚创建的RuleConditionReference。生成的代码如下:
System.Workflow.Activities.Rules.RuleConditionReference ruleconditionreference1 = new
System.Workflow.Activities.Rules.RuleConditionReference(); this.ifElseBranchActivity1 = new System.Workflow.Activities.IfElseBranchActivity(); ruleconditionreference1.ConditionName = "rule1"; this.ifElseBranchActivity1.Condition = ruleconditionreference1; this.ifElseBranchActivity1.Name = "ifElseBranchActivity1";
了解了这个过程我们来看看.Rules文件中的内容,我们上面简单为IfElseActivity设置了一个简单的规则条件生成的
.rules如下:
<RuleDefinitions xmlns="http://schemas.microsoft.com/winfx/2006/xaml/workflow"> <RuleDefinitions.Conditions> <RuleExpressionCondition Name="rule1"> <RuleExpressionCondition.Expression> <ns0:CodeBinaryOperatorExpression Operator="ValueEquality" xmlns:ns0="clr-
namespace:System.CodeDom;Assembly=System, Version=2.0.0.0,
Culture=neutral, PublicKeyToken=b77a5c561934e089"> <ns0:CodeBinaryOperatorExpression.Left> <ns0:CodePropertyReferenceExpression PropertyName="Test"> <ns0:CodePropertyReferenceExpression.TargetObject> <ns0:CodeThisReferenceExpression /> </ns0:CodePropertyReferenceExpression.TargetObject> </ns0:CodePropertyReferenceExpression> </ns0:CodeBinaryOperatorExpression.Left> <ns0:CodeBinaryOperatorExpression.Right> <ns0:CodePrimitiveExpression> <ns0:CodePrimitiveExpression.Value> <ns1:String xmlns:ns1="clr-namespace:System;Assembly=mscorlib,
Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"></ns1:String> </ns0:CodePrimitiveExpression.Value> </ns0:CodePrimitiveExpression> </ns0:CodeBinaryOperatorExpression.Right> </ns0:CodeBinaryOperatorExpression> </RuleExpressionCondition.Expression> </RuleExpressionCondition> </RuleDefinitions.Conditions> </RuleDefinitions>
我们可以清晰的看到,生成的.rules文件中规则以代码 DOM 语句的形式表示。WF使用.NET Framework 中的 System.CodeDom
提供的类型。可以使用这些类型来创作您的条件。 一些类型在条件中受支持,一些类型在规则操作中受支持,一些类型在两者中都
受支持。
下列各表显示支持的 System.CodeDom 类型。
类 | 用于 |
CodeArrayIndexerExpression | 条件,操作 |
CodeAssignStatement | 操作 |
CodeBinaryOperatorExpression | 条件,操作 |
CodeCastExpression | 条件,操作 |
CodeDirectionExpression | 条件,操作 |
CodeExpressionStatement | 操作 |
CodeFieldReferenceExpression | 条件,操作 |
CodeIndexerExpression | 条件,操作 |
CodeMethodInvokeExpression | 条件,操作 |
CodeMethodReferenceExpression | 条件,操作 |
CodePrimitiveExpression | 条件,操作 |
CodePropertyReferenceExpression | 条件,操作 |
CodeThisReferenceExpression | 条件,操作 |
CodeTypeReference | 做为表达式的一部分 |
CodeTypeReferenceExpression | 条件,操作 |
CodeBinaryOperatorType | 支持上下文 |
Add | 条件,操作 |
BitwiseAnd | 条件,操作 |
BitwiseOr | 条件,操作 |
BooleanAnd | 条件,操作 |
BooleanOr | 条件,操作 |
Divide | 条件,操作 |
GreaterThan | 条件,操作 |
GreaterThanOrEqual | 条件,操作 |
IdentityEquality | 条件,操作 |
IdentityInequality | 条件,操作 |
LessThan | 条件,操作 |
LessThanOrEqual | 条件,操作 |
Modulus | 条件,操作 |
Multiply | 条件,操作 |
Subtract | 条件,操作 |
ValueEquality | 条件,操作 |
这两种方式我们比较推荐使用规则条件,因为他是规则引擎中的一部分可以更灵活而且可以在工作流实例运行后动态的更新。