Well now, this was a fine how-do-you-do on a Wednesday morning...
http://footheory.com/blogs/bennie/archive/2007/05/12/simple-application-extensibility-with-wf-rules.aspx
Holy cow! Turns out the rules engine that ships with WF is usable in your own application, even if you're not using workflows at all! This is incredibly cool. A little background for the uninitiated...
Windows Workflow is a technology that ships with .NET 3.0. It enables you to express program logic and control flow visually, in what looks a bit like a Visio diagram. It directly enables things like continuations and passivation in your software. It is, in general, a Very Big Deal... though it usually plays second fiddle to WPF and WCF when folks start discussing .NET 3.0.
One of the features of WF is a business rules engine that can be used to author and execute rules against workflows in your application. The rules work against internal workflow state, and produce side effects during execution to modify that state in some meaningful way. For example, your workflow might expose properties such as AccountName or OrderAmount, so a simple rule might be (in pseudo-code):
if this.OrderAmount > 100
then this.Discount = 10%
else this.Discount = 0%
The idea is that you express such rules out-of-band from your code, which provides really nice maintenance and visibility benefits. Since rules tend to be the core value of a software system, they're best not buried inside layer after layer of C# code where only a programmer can maintain them.
You get an out-of-the-box editor with Intellisense for rule authoring. In addition, there are standard hooks in WF (through the use of PolicyActivity, typically) for invoking the rules at runtime. This all works great assuming you're authoring and using workflows in your application.
Okay... so here's the neat part. You can use this rules engine even if you aren't using workflows. There's a great sample on the WF community site that demonstrates how to re-host the rules designer in your own application, as well as how to use alternate storage mechanisms for rules (by default, rules are saved to a file in your workflow project, and the file is compiled as a resource). But, that code is still relying on workflows and custom policy activities to execute rules. So the code from this sample is used in the other sample found at the link I mentioned at the top of this post to demonstrate rule execution without workflow involved at all. I also re-purposed the base sample code to whip up my own demo app.
Here's a screenshot of rule authoring against my own "User" type (which has properties like Name and Age):
Notice the full Intellisense support for my custom type... this makes rule editing a breeze.
Once you edit and save your rules (storage is just a single table in the SQL database of your choice), you can then reference the rules (sets of rules, actually) by name at runtime, for execution. Here's a code snippet:
// create my user object...
User joe = new User();
joe.Name = "Joe";
joe.Age = 35;
joe.Valid = false;
// next several lines execute the ruleset called "User2"...
RuleSetService svc = new RuleSetService();
RuleSet ruleset = svc.GetRuleSet( new RuleSetInfo( "User2" ) );
RuleExecution exec
= new RuleExecution( new RuleValidation( joe.GetType(), null ), joe );
ruleset.Execute( exec );
// okay, ruleset has executed, let's see what the outcome is...
Console.WriteLine( joe.Valid.ToString() );
And that's it... about 4 lines of code to invoke a ruleset at runtime. And again... no workflow in sight. Not that I have anything against workflows, it's just nice to know you can use the rules engine by itself if/when needed.
I've uploaded my own sample application here. Grab it, unzip, restore the database backup, check your config file connection strings, and party on. There are 5 VS.NET 2005 projects included... 4 of them are modified versions of the code found in the previously mentioned WF community site sample, the other (called "Tester") is my own sample that exercises some rules I created through the designer. So just to be clear... most of this is not my own code. But that also speaks to the beauty of this approach... most of the heavy lifting is done for us already, so it's easy to get up and running.
Enjoy!
Don't blame my employer(s)... all of this is my fault.