Sunday, September 16, 2007

Microsoft.RuleEngine.XmlHelper

Recently I have a requirement for a project involving the use of the BRE. The customer wanted to know which rules were being evaluated. They wanted to know the outcome of each of the business rules as they were applied to the facts submitted. More importantly, they wanted to know why *each* of the rules failed.

Here are the requirements
NumberDays >= 300
StateEmployment = OH
HoursWorked >= 1000
Gender = M
Condition = Final
The solution to these requirements was to implement a MAIN Policy that will test and evaluate for all conditions. Then writing a single business rule for each fact and negating that, would take care of the reasons for the policy to fail.

To maintain a list of those failed business rules, we can make use of the XMLHelper class that comes with the Business Rule Engine Assembly.

The first step is to add a reference to Microsoft.RuleEngine assembly. On the .NET Classes tab, right click and select Browse.


Now select the Microsoft.RuleEngine assembly.


After you click OK, you can see all of the interfaces exposed by this assembly. Select the Microsoft.RuleEngine.XMLHelper one, and you will see the methods


As you can see, there are several overloaded methods for the AddNode function. We will use this function to keep track of executed business rules.
Here is the schema that I will be using to illustrate the use of this handy feature:

I will be evaluating the information in the INPUT node, and I will be updating the information on the OUTPUT node. Inside the RulesApplied, there will be a node of RULE that will contain each business rule that was evaluated.

Here is the sample output xml that I should get after the BRE executes:

    1 <ns0:Root xmlns:ns0="http://AW.SampleSchema.v1">
    2     <Input>
    3         <NumberDays>300</NumberDays>
    4         <StateEmployment>OH</StateEmployment>
    5         <HoursWorked>1000</HoursWorked>
    6         <Gender>X</Gender>
    7         <Condition>yxyxyx</Condition>
    8     </Input>
    9     <Output>
   10         <OutputStatus>false</OutputStatus>
   11         <RulesApplied>
   12             <Rule>
   13                 <RuleName>negGender</RuleName>
   14                 <RuleMessage>not a valid gender</RuleMessage>
   15             </Rule>
   16             <Rule>
   17                 <RuleName>negCondition</RuleName>
   18                 <RuleMessage>not a valid condition</RuleMessage>
   19             </Rule>
   22         </RulesApplied>
   23     </Output>
   24 </ns0:Root>

For this implementation, I will have one main business rule and 5 negative rules that will give me the reasons for failure.



The MainTest would look like this:


and each of the negative test will be a single test with the NOT predicate:


For the actions, I will be adding a RULE node to each negative rule. The important thing to remember in this xmlHelper is the xpath function:
./Rule[position()=last()]

This xpath function will place the insert location at the last position.

The Actions panel for the Main test will be:


The Actions panel for the negative rules will look something like this:


Notice that the first action is a call to the XmlHelper.AddNode. This will add the parent node named Rule.

Then there are 2 calls to the XmlHelper.AddNodeWithValue. These calls will add the child nodes and their corresponding value.

The default value for the outputStatus field is set to False by default. Then I only update that value if the MainTest passes.

Ahh. more importantly, read this article from Richard Seroter regarding static objects. You will need to add a value on the registry to get this function to work. On a windows 2003, the location will be:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\BusinessRules\3.0\StaticSupport

but on a Vista x64, the location is HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\BusinessRules\3.0\StaticSupport

3 comments:

Unknown said...
This comment has been removed by the author.
Anonymous said...

Nice post man,

really what I was looking for ...

keep up the good work

Unknown said...

Very nice, I will try the same.
Thank you VERY MUCH for posting this, you saved my life :-)