Insist on learning WF Article Index
This time, I will continue to learn about the rules engine in WF. Each rule in WF includes the following three parts:
1. A condition returns true or false.
2. One then operation (executed when the condition is true)
3. An else operation (executed when the condition is false)
The rule corresponds to the rule class in the system. workflow. Activities. Rules namespace. The thenactions and elseactions of the rule class are the set of ruleaction objects. Ruleaction is an abstract class. Its derived class rulestatementaction specifies the attribute or field to be updated or the method to run with the codedom type. There are also rulehaltpneumatic and ruleupdateaction Derived classes. Rulestatementaction can use simple fielda = 10, or complex calculation fielda = fieldc * 3.14. The statement block of rulestatementaction will be serialized as a codedom object, and the codedom object will identify the internalSource codeCan be dynamically generated and compiled. If you use the rule editor, you do not need to understand its details, but you need to dynamicallyCodeTo declare rules, you should have a good understanding. The rulehaltaction class causes the ruleset to stop execution and re-return the control to the calling method. The ruleupdateaction class indicates to the rule engine that the operation set for executing this rule can cause the specified field or attribute (or all fields and attributes of an object) to change, this allows you to recalculate any rules that depend on this field or attribute. The update call does not block the execution of other operations in the action block. The link to the modified field/attribute set (specified by update or by using rulewriteattribute for the called method) used to determine when the operation set of this specific rule is executed.
We can regard the rule as an if-then-else statement, where the condition corresponds to IF, and the operation defines the behavior of the then and else clauses. Such a group of rules forms the Rule Set ruleset. The rule set supports both simple and sequential execution of rules and complex forward links of rules. The rule set can be executed by the policyactivity. When using a policyactivity activity, we only need to drag the activity to the workflow designer, configure the rulesetreference attribute on policyactivity, and point it to the ruleset in rulesetcollection by name. The policyactivity creates an instance of the ruleset class. Rules are executed by the ruleset class. For the Rule Set Editor in vs2008:
We can see that each rule has a priority attribute, which is executed first. Although setting priority can change the execution sequence of rules in a rule set, this attribute is generally not set because the Rules Engine of WF has the ability to re-calculate (Forward Chaining) Forward links. Next I will talk about the forward link feature that is very important in the rule engine.
Forward link
The chainingbehavior attribute of the ruleset class indicates getting or setting the forward link behavior of the rule class in the ruleset. Determines how the rule engine executes forward links. The value of this attribute is the enumeration type rulechainingbehavior. The following describes the values:
None (sequential): indicates that the link is not executed. Each rule is executed only once.
Updateonly (display update only): indicates that the link is executed if the executed operation uses ruleupdateaction to explicitly specify a link.
Full: indicates that the link is executed when the operation modifies the field or attribute, specifies rulewriteattribute for the method called by the operation, or executes ruleupdateaction.
The following is an example:
Rule |
Conditon |
Thenaction |
Elseaction |
Rule1 |
A> 10 |
B = 60 |
B = 40 |
Rule2 |
B> 50 |
C = "preferred" |
C = "normal" |
Rule3 |
D <0, 100 |
B = B * 0.80. |
|
We can see that A and D are input variables, and B and C are set in rules. If we use the completely forward link option, the rule engine automatically determines whether to re-calculate the previous rule based on these rules. For example, if a is 12 and D is 99,
1. rule1 A> 10 so B = 60
2. To rule2 B = 60, greater than 50, so c = "preferred"
3. rule3 d = 99 <100 so B = 60*0.80 = 48
4. At this time, the value of B = 48 and B has changed, so rule2 will recalculate and B <50 c = "normal"
5. rule3 does not re-calculate because the variables it contains have not changed since the first calculation.
The final result is B = 48, c = "normal", and a D does not change. If you set the property of the forward link to none, each rule will be executed once, and the final result will be B = 48, c = "preferred ".
Update statement
Sometimes we do not need a full forward link. We use the updateonly and updateonly options to disable implicit and attribute-based links, and stipulate that links should only occur in explicit update statements. This allows you to fully control which rules cause re-calculation. In this case, we must use the update statement, which tells WF that an attribute will be modified and relevant rules may need to be applied again.
The following is an example,
rule |
conditon |
thenaction |
elseaction |
rule1 |
A> 10 |
B = 60, update (B) |
B = 40, update (B) |
rule2 |
B> 50 |
C = "preferred", update (c) |
C = "normal", update (c) |
rule3 |
d <100 |
B = B * 0.80, update (B) | & Lt; TD width = "168" valign = "TOP" & gt; & lt;/TD & gt;
The update statement is serialized. the ruleupdateaction is generated when the Rules file is used. Each update statement indicates whether it is changed by other conditions. Using this option can avoid loop dependencies that lead to excessive (or even out of control) Execution of rules, alternatively, you can improve the performance by eliminating the rules that are not required to provide the functional integrity of the ruleset.
Disable rule Recalculation
Another item that affects rule calculation is the reevaluationbehavior attribute of the Rule class. It gets or sets a value that indicates whether the rule can be recalculated. The value is rulereevaluationbehavior. The default value is always, and the never corresponds to the recalculation option shown in the figure above.
Always: the default value. It provides the previously discussed behavior, that is, the Link re-calculation rule is always caused by the operation of other rules.
Never: as its name implies, it is to disable re-computing. The rule is calculated once, but if the rule has previously performed any operation, it is not recalculated. In other words, if the rule is previously computed and therefore its then or else operation is executed, the rule will not be recalculated. However, the empty operation set in the then or else operation does not indicate that the rule has been executed.
Attribute-based
When the condition or execution of a rule is a field or attribute, the Rules Engine of WF can identify their relationship to control forward links. If it is a method, it will not work, such as the getaccountstatus method, we can guess that this method is to get the account status value, but WF can't guess it. We use the following set of attributes to solve this problem.
A total of three rulereadattriattribute, rulewriteattribute, and ruleinvokeattribute classes indicate the attributes used to read conditions, write operations, and call methods respectively. Attribute to indicate which conditions are modified. The following is an example:
Rule |
Conditon |
Thenaction |
Rule1 |
This. Discount> 0 |
This. Total = (1-this.discount) * This. Subtotal |
Rule2 |
This. Subtotal> 10000 |
This. setdiscount (0.05) |
Then, you can set the setdiscount method as follows. This enables the engine to identify that Rule 1 depends on Rule 2 because the discount field is used.
[Rulewrite ("discount")] void setdiscount (double requesteddiscount) {... // some code that updates the discount field .}
Rulereadattribute and rulewriteattribute have the same usage. The ruleinvokeattribute can be used to indicate the links
Method. For example, assume that the rules and methods are modified as follows:
Rule |
Conditon |
Thenaction |
Rule1 |
This. Discount> 0 |
This. Total = (1-this.discount) * This. Subtotal |
Rule2 |
This. Subtotal> 10000 |
This. setdiscountwrapper (0.05) |
[Ruleinvoke ("setdiscount")]
Void setdiscountwrapper (double requesteddiscount)
{
Setdiscount (requesteddiscount );
}
[Rulewrite ("discount")]
Void setdiscount (double requesteddiscount)
{
}
The following describes how to use attributes:
-
you can use attributes to specify how to use parameters in methods. For example, you can set attributes in the following method to indicate that this method modifies the discount attribute (property) on the passed Order instance ).
[rulewrite ("currentorder/discount", ruleattributetarget. parameter)] private void setdiscount (Order currentorder, double discount) {currentorder. discount = discount ;}
-
wildcards can also be used in rule attributes. For example, you can use rulewrite ("order/*") to instruct this method to modify all fields on the object referenced by the "order" field. However, wildcards can only be used at the end of a path. attributes such as rulewrite ("*/discount") are invalid.
-
attributes such as rulewrite ("order") can be used with the reference type to indicate that the reference has been changed. For example, the variable currently points to another order instance. In addition to all rules referenced by the test instance, all rules using the field/attribute are assumed to be affected. For example, if this. Order = This. order2.
-
the default behavior when no method attribute is specified is assumed that the method is called on the target object (that is, the object of the method called on it) do not read or write any field/attribute. In addition, it is assumed that the method call reads and writes parameters according to the keywords defined in. NET Framework (such as REF, out, byval, and byref.