Guy Burstein's Blog

All about the newest tools and technologies from Microsoft

News

Guy Burstein
Work:
Microsoft Israel, 2 Hapnina st', Raanana
Israel
Email:
Or, use this form.
Guy Burstein The Bu

Disclaimer
Postings are provided 'As Is' with no warranties and confer no rights.

Guy Burstein LinkedIn Profile

TwitterCounter for @bursteg

The Bu

Links

Articles

Blogs I Read

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!

Comments

No Comments