Build workflow rules using Code Dom and Rules API
A short reminder about rules and conditions
Condition - Expression that evaluates to True or False
Rule – Modeled as:
If <Condition>
Then <RuleAction(s)>
Else <RuleAction(s)>
RuleSet - Collection of Rules with a set of execution semantics.
The RuleSet Editor that ships with Windows Workflow Foundation may be very convenient for developers, but for the end-user or even the business analyst it might not.
Building another user interface for editing rules, developers use CodeDom in order to create their rules conditions and actions on-the-fly.

Both conditions and actions are just code expressions or statements expressed with CodeDom. In order to use them in the context of rules, they must be wrapped with designated wrappers.
Assuming that my custom object (which the rules will be executed on) look like:
public class Technology
{
public Technology(string tech)
{
this.technology = tech;
this.rocks = false;
}
private string technology;
private bool rocks;
public string TechnologyName
{
get { return technology; }
set { technology = value; }
}
public bool Rocks
{
get { return rocks; }
set { rocks = value; }
}
}
Now, I want to create a rule that checks if the technology name is “WF”, and sets rocks property if it is. Describing it with (pseudo) code, the rule looks like:
if (this.Technology == "WF")
this.Rocks = true;
else
this.Rocks = false;
Let’s separate the code required to build this rule into several parts:
Building the Condition
// this.
CodeThisReferenceExpression thisRef = new CodeThisReferenceExpression();
// .Technology
CodePropertyReferenceExpression technologyRef = new CodePropertyReferenceExpression(thisRef, "TechnologyName");
// "WF"
CodePrimitiveExpression wfConstant = new CodePrimitiveExpression("WF");
// if ( this.Technology == "WF" )
CodeBinaryOperatorExpression cond = new CodeBinaryOperatorExpression();
cond.Left = technologyRef;
cond.Operator = CodeBinaryOperatorType.ValueEquality;
cond.Right = wfConstant;
Building the ThanAction and ElseAction
// .Technology
CodePropertyReferenceExpression rocksRef = new CodePropertyReferenceExpression(thisRef, "Rocks");
// true
CodePrimitiveExpression trueExpression = new CodePrimitiveExpression(true);
// false
CodePrimitiveExpression falseExpression = new CodePrimitiveExpression(false);
// this.Rocks = true;
CodeAssignStatement assignTrue = new CodeAssignStatement();
assignTrue.Left = rocksRef;
assignTrue.Right = trueExpression;
// this.Rocks = true;
CodeAssignStatement assignFalse = new CodeAssignStatement();
assignFalse.Left = rocksRef;
assignFalse.Right = falseExpression;
Wrapping with Workflow Rules objects
// Wrap it all togother
Rule rule = new Rule("rule1");
rule.Condition = new RuleExpressionCondition(cond);
rule.ThenActions.Add(new RuleStatementAction(assignTrue));
rule.ElseActions.Add(new RuleStatementAction(assignFalse));
// Create a RuleSet
RuleSet rs = new RuleSet();
rs.ChainingBehavior = RuleChainingBehavior.None;
rs.Rules.Add(rule);
Executing the RuleSet over an instance of Technology class
Technology t1 = new Technology("WF");
// Validate RuleSet
RuleValidation validation = new RuleValidation(typeof(Technology), null);
rs.Validate(validation);
ValidationErrorCollection errors = validation.Errors;
if (errors.Count > 0)
{
// TODO: Check if there are any errors and handle
}
// Execute
RuleExecution execution = new RuleExecution(validation, t1);
rs.Execute(execution);
Console.WriteLine("{0} {1}!", t1.TechnologyName, (t1.Rocks ? "Rocks" : "does not rock at all!"));
What is the expected result?
Enjoy!