Processing Collections in Rules
In some scenarios, you might have to evaluate rules against all items individually in a collection. Iterating over the collection can be done in several ways, but one way is with a rule pattern such as this: Create additional rules to handle iterating the items in the collection that execute before and after the rules that evaluate the individual items themselves. In this example the workflow has a List of integers, a currentItem
member, and an IEnumerator member.
public List<int> items;
public IEnumerator<int> enumerator;
public int currentItem;
The desired rule behavior in this example is to evaluate each individual item in the collection and write a message to the console indicating if the item is even or odd.
IF this.currentItem % 2 == 0
THEN System.Console.WriteLine("{0} is even", this.currentItem)
ELSE System.Console.WriteLine("{0} is odd", this.currentItem)
To accomplish this, additional rules must be added to execute before this rule to initialize the enumerator and iterate the items in the collection.
// Rule 1 with Priority of 2 so it executes first
IF True
THEN this.enumerator = this.items.GetEnumerator()
// Rule 2 with Priority of 1 so it executes second
IF this.enumerator.MoveNext()
THEN this.currentItem = this.enumerator.Current
Once the enumerator is initialized and the current item in the collection is saved in currentItem
, any rules that evaluate the individual items are evaluated. In this example there is just one rule.
// Rules 3-N with Priority of 0 so they execute after the first two rules
IF this.currentItem % 2 == 0
THEN System.Console.WriteLine("{0} is even", this.currentItem)
ELSE System.Console.WriteLine("{0} is odd", this.currentItem)
Once any rules that use the individual item complete, a final rule must be added to move to the next item in the collection.
// Rule N+1 with Priority of -1 (lowest Priority in RuleSet)
IF this.currentItem == this.currentItem
THEN Update("this/enumerator")
When this rule executes, the Update command instructs the rules forward chaining engine to schedule Rule 2
for reevaluation because it evaluates the workflow enumerator member in its Condition. Rule 2
advances the enumerator to the next item in the collection and this process repeats until all the items in the collection have been evaluated. For more information about the Update command, see Forward Chaining of Rules.
Note
All rules in a RuleSet are evaluated at least once unless an explicit Halt command is given. If the collection has zero elements then this can cause unexpected behavior when the RuleSet executes. This can be prevented by placing a Halt command in the Else action of Rule 2, which stops processing of the RuleSet when MoveNext returns false, which occurs when there are no items in the collection. If there are subsequent rules that should execute even if there are no items in the collection then the Halt command should not be used, but additional constraints can be added in the individual rules to verify that the collection contains items. For more information about the Halt command, see Forward Chaining Control.
If the enumerator pattern does not meet the requirements of your application, you can use a similar pattern of rules to increment a counter that you can use as an index into your collection.
See Also
Reference
Concepts
Using RuleSets in Workflows
Rules Evaluation in RuleSets
Forward Chaining of Rules
Forward Chaining Control