DCSIMG
Build workflow rules using Code Dom and Rules API - Guy Burstein's Blog

Guy Burstein's Blog

Developer Evangelist @ Microsoft

News

Guy Burstein The Bu

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

Guy Burstein LinkedIn Profile

TwitterCounter for @bursteg

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

Guy Burstein's Blog said:

This is my #200 post, and it is a good time to look back at what I've posted over the last few months.

# March 9, 2007 8:52 PM

Guy Burstein's Blog said:

Using WF Rules Engine without any Workflow Customer often ask me: "If all I need is the WF Rules Engine

# August 9, 2007 6:53 PM

Guy Burstein's Blog said:

This post talks about the posibility of using the WF Rules Engine not inside a business process developed by Windows Workflow Foundation

# August 9, 2007 6:54 PM

Paresh Gheewala said:

This is a perfect snippet I was looking for. this can be used to solve even generic expressions and dynamic assignment. however I have modified changes to my code.

thanks to Guy Burstein...

-Paresh

# August 4, 2008 12:36 AM

newbie said:

Thanks for the article.  

Sorry for the newbie questions but must there be a target object (the custom Technology in the case of this example) in order to use the codeDom?  would like to explore the possibility to use codedom for a generic rules engine but if the target object is required, i am not sure if that can be done.  any guideline will be appreciated.  Thanks again.

# August 10, 2008 12:48 PM

senthil said:

Thanks

 Its give me little bit idea on work Flow condition.

# August 23, 2008 11:31 AM

thrillertip said:

comment2,

# March 4, 2009 12:47 AM

pri said:

help

# March 19, 2009 2:36 PM
Leave a Comment

(required) 

(required) 

(optional)

(required) 


Enter the numbers above: