A quick and dirty Rules Engine using Windows Workflow (Part 1)


Recently I put my mind towards developing a fairly light rules based utility for applying various logical patterns on top of some linear business data.  Honestly, my initial thoughts were “oh no, not another boring rules based implementation” because we (ought to) know how boring that can be – and convoluted – but this time I decided to try something a little different.

Through no fault of my own, I’ve actually had very little to do with Windows Workflow Foundation – WF, not WWF which stands for World Wildlife Foundation, and not to be confused with the World Wrestling Federation, just to avoid confusion!

Most of the project I’ve worked on previously have used some other workflow product, usually something like K2 blackpearl or a custom implementation, for example.  In any case, I’ve always been curious – from what I’d heard it kicks Sharepoint’s “workflow” (if you could call it that) in the butt.  I’m all for that!

Now, from my admittedly sparse knowledge of WF, I knew there was some sort of Rules Engine sitting somewhere near some sort of Workflow for Business Analyst, and it reminded me of a demo I’d seen a little while back involving a graphical interface to design business rules.  Don’t fear, this is way cooler than that!

Anyhow, to cut a long and boring intro short (too late?) I got stuck into designing a quick and dirty rules engine for working with Data Transfer Objects or POCO entities.  Actually, you can pretty much use whatever object you like, it’s very unassuming :)

To start out, you need to add a reference to the following .Net assemblies, available in the .Net Framework v3.0 and onwards:

System.Workflow.Activities
System.Workflow.ComponentModel
system.Workflow.Runtime

So just add them to the project you are working with, and you’re half way there.  Next, lets start off by actually creating some rules, or at least a mechanism to do so.  This is almost too easy for words, so let us take a look at some code instead:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Workflow.Activities.Rules.Design;
using System.Workflow.Activities.Rules;
using System.Windows.Forms;
using System.Workflow.ComponentModel.Serialization;
using System.Xml;
using System.IO;

public static class CreateRulesHelper
{
    public static void LaunchRulesDialog(string outputPath)
    {
        RuleSet ruleSet = null;

        // You could pass in an existing ruleset object for editing if you wanted to, we're creating a new rule, so it's set to null
        RuleSetDialog ruleSetDialog = new RuleSetDialog(typeof(BasicTerm), null, ruleSet);
            
        if (ruleSetDialog.ShowDialog() == DialogResult.OK)
        {
            // grab the ruleset
            ruleSet = ruleSetDialog.RuleSet;
            // We're going to serialize it to disk so it can be reloaded later
            WorkflowMarkupSerializer serializer = new WorkflowMarkupSerializer();

            string fileName = String.Format("BusinessRule{0}.rules", DateTime.Now.Millisecond);
            string fullName = Path.Combine(outputPath, fileName);

            if (File.Exists(fullName))
            {
                File.Delete(fullName); //if it bleeds, we can kill it
            }

            using (XmlWriter rulesWriter = XmlWriter.Create(fullName))
            {
                serializer.Serialize(rulesWriter, ruleSet);
                rulesWriter.Close();
            }
        }
    }
}

See? This is a basic implementation inside a static class and essentially launches the WF rules engine editor.  I’m not doing anything fancy here, just taking whatever the user does and serializing it to disk (to be loaded later).  Some key things to point out here:

  1. I’m always creating a new ruleset – you could rewire this to allow editing of existing rules
  2. You may notice I’m using a random file name.  A more detailed implementation could take some input to form the rule name
  3. I’m using a specific object type (“BasicTerm”) – check back for Part 2 when I’ll rework this code so you can use it with different object defintions
  4. This is just a quick mock up!  Sample purposes only :)

Now assuming you had an object called “BasicTerm” and you compiled and ran this code, you’d get prompted with a window not unlike this one:

image image

The best part?  It has IntelliSense too!  You can create some very interesting IF..THEN..ELSE runs here, and you can create multiple rules per rule set.  The neat part is that you can modify the object directly, although it is somewhat limiting, it could be a very handy asset for something like message based routing rules (like in BizTalk).

I won’t go into too much detail at this juncture, other than encouraging you to have a play with this relatively simple interface.  Once you’ve set some rules (or even if you set none) – provided you click OK, you’ll get a .rules file written out to disk.  Check back for Part 2 where I’ll demonstrate how we can use these rules in a quick and dirty workflow.

Continued in Part 2

Further Reading

Introdution to the Windows Workflow Foundation Rules Engine

How to use Windows Workflow Rules


About Rob Sanders

IT Professional and TOGAF 9 certified architect with over 16 years experience, 14 in commercial software development and 8 years in IT consulting. Check out the "About Rob" page for more information.

Leave a comment

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>