Build workflow rules using Code Dom and Rules API

4 בדצמבר 2006

5 comments

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!

Add comment
facebook linkedin twitter email

5 comments

  1. Paresh Gheewala4 באוגוסט 2008 ב 0:36

    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

  2. newbie10 באוגוסט 2008 ב 12:48

    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.

  3. senthil23 באוגוסט 2008 ב 11:31

    Thanks

    Its give me little bit idea on work Flow condition.

Comments are closed.