Business Rules Engines

45
Programming with the Microsoft Business Rules Framework Business Rules are pervasive in software. In fact, in most cases, business rules are the very reason for the existence of most software today. As application architectures have become more and more sophisticated, few can disagree with the merits of separating the presentation layer from the business layer or the data layer from the business layer. Yet many applications today are still built with process logic and business rules interwoven within the same business/application layer, which can lead to applications that are brittle, hard to maintain, and resistant to change. In this article, I will explain how to decouple the business rules within your application in a manner that yields high organizational visibility and accountability; and promotes rules as a unit of reuse to help you build applications that are ready for change. When Rod Paddock and I first started talking about ideas for this article, my goal was to share some of the techniques I have successfully implemented for exposing the Microsoft Business Rules Engine (BRE) via services. Always the wise pragmatist, Rod suggested that I first start with an introduction. If my experience delivering two talks on the subject this year at Austin Code Camp and Desert Code Camp in Phoenix are any indication, he's probably right. Both sessions were well attended, and most attendees had heard of rule-based engines, but had not taken it much further. This intrigues me, because there is a growing developer community that really understands the benefits of dependency injection, inversion of control, and contract-first development. I think that anyone interested in such techniques should look closer at rule-based engine technology

Transcript of Business Rules Engines

Programming with the Microsoft Business Rules Framework

Business Rules are pervasive in software. In fact, in most cases, business rules are the very

reason for the existence of most software today. As application architectures have become more and

more sophisticated, few can disagree with the merits of separating the presentation layer from the

business layer or the data layer from the business layer. Yet many applications today are still

built with process logic and business rules interwoven within the same business/application layer,

which can lead to applications that are brittle, hard to maintain, and resistant to change. In this

article, I will explain how to decouple the business rules within your application in a manner that

yields high organizational visibility and accountability; and promotes rules as a unit of reuse to

help you build applications that are ready for change.

When Rod Paddock and I first started talking about ideas for this article, my goal was to share

some of the techniques I have successfully implemented for exposing the Microsoft Business Rules

Engine (BRE) via services. Always the wise pragmatist, Rod suggested that I first start with an

introduction. If my experience delivering two talks on the subject this year at Austin Code Camp

and Desert Code Camp in Phoenix are any indication, he's probably right. Both sessions were well

attended, and most attendees had heard of rule-based engines, but had not taken it much further.

This intrigues me, because there is a growing developer community that really understands the

benefits of dependency injection, inversion of control, and contract-first development. I think

that anyone interested in such techniques should look closer at rule-based engine technology

because it is a way to accomplish or, at the very least, compliment many of these techniques. So,

while my initial goal of going deeper with the technology will have to wait, I hope that you will

discover how valuable (and cost effective) incorporating a rule-based engine into your solution

architecture and design can be.

What Are Business Rules?

The Business Rules Group, a non-commercial organization that helps to define and disambiguate the

definition of business rules defines a business rule as "a statement that defines or constrains

some aspect of the business. It is intended to assert business structure or to control or influence

the behavior of the business." The Business Rules Group further defines business rules as

organizational "guidance that there is an obligation concerning conduct, action, practice, or

procedure within a particular activity or sphere."

"

______________________________________________________________________________________________

The industry has widely accepted as best practice to separate the data layer from the business

layers.

______________________________________________________________________________________________

"

To take a practical example, a business rule may read like this:

"If the customer is a preferred member, always apply a 10% discount on the total checkout price."

Take a moment and re-read the Business Rule Group's definition in the first paragraph above. With

this perspective, the significance of this rule is profound. With very little knowledge about the

business, it is evident that the company sells products or services to individuals, and elite

customers who hold a membership status are entitled to receive a 10% discount on purchases. This

rule is likely part of an organizational customer loyalty and marketing strategy, as the business

rule is almost certainly designed to motivate customers to pay an annual premium for membership

status. At a minimum this rule governs the activity of purchasing goods by influencing the behavior

of preferred members to purchase higher-dollar purchases since they will be modestly discounted.

This is only one example. Think about the business rules that govern the applications you have

built in the past or the project you are currently on. As developers, we wield incredible power-and

responsibility-for ensuring that these business rules are elicited, developed, deployed, and

maintained as accurately and efficiently as possible. As you can imagine from the example, there

are a number of team roles that come into the lifecycle of a business rule, yet as developers we

tend to hide these rules in the bowels of code bases that will rarely if ever be visible to other

team roles, and when we are asked to change or remove a rule after the application has been

deployed we naturally resist. Why!? Because change is hard unless your application is built to

evolve, and if there is one area of your application that is almost guaranteed to change, it is the

business rules. Business rules need to be dynamic just like the business itself. Rule-based engines

allow you to harness this change by making business rules management completely transparent across

all interdependent team roles while providing very high run-time performance. In addition to

visibility and performance, rule-based engines support the loosely coupled integration of business

rules into applications that use them.

Rule Engine Fundamentals

All rule-based engines are similar in that they allow various roles within an organization to

author, save, deploy, and interact with business rules in a centralized manner that allows

disparate applications to consume the rules in a managed, service-oriented manner. As such, most

rule-based engines provide a rule editor, which allows you to author and save business rules; a

shared rules repository for persisting and looking up rules; a high-performance rules engine for

executing rules in the repository; and administrative tools for deploying, retiring, and migrating

rules from one rule repository to another.

How We Got Here

Since the dawn of computing, our forefathers and contemporaries alike have been hard at work

chipping away at the same problem: how to break apart the monolith by decoupling as many components

as possible without sacrificing performance. Ever since the first computer, the trend has been

constant. Computing has moved from sprockets and dials to assembly languages and onto procedural,

object-oriented, component-oriented, and service-oriented designs, which further lubricate

interaction between constituent parts of a system. Each of these evolutionary technologies has

ushered in refined architectures such as 2-tier, n-tier, and service-oriented architecture.

The industry, in building scalable systems that are also maintainable, has widely accepted as best

practice to separate the data layer from the business layers. The user interface and business

layers have evolved as well, making the logical separation of user interfaces and business layer

physical with the advent of distributed component technologies. Even platform and vendor coupling

has proven to be undesirable, and today components can communicate with one another using messaging

standards sanctioned by non-proprietary standards bodies such as W3C and Oasis.

With business rules being such a critical part of any application architecture, there are likely

great opportunities for decoupling business rules from the main application or process layer.

Often, the idea with decoupling is that the less one component or service knows about the other,

the more free each component or service is to change and evolve. The same is true for business

rules, and this is the heart of the case for using a rule-based engine.

Why Use a Rule-based Engine?

A rule-based engine isolates business rules from the application making the rules eminently

reusable. Since business rules are (or should be) organizationally universal-as opposed to

application specific-rule-based engines can provide unprecedented reuse (another goal of

decoupling) of business rules. In addition, business rules that are visible to mere mortals

(non-developers) are much better understood and this transparency introduces higher accountability

within teams. In software development, a team is not just comprised of developers and architects.

While these roles are very important, software product development includes stakeholders,

line-of-business managers, business analysts, and quality assurance analysts to name just a few.

A recent report in CIO Magazine found that up to 70% of CIO budgets are spent on maintenance. Even

conservatively, if you assume that half of the maintenance costs are attributed to business rules

maintenance; it is likely that upward of 35% of IT budgets are spent managing business rules. A

recent report by IDC supports these numbers. According to IDC, three-year net ROI for organizations

deploying rule-based engines is in excess of 100% through 25%-80% reductions in development costs.

The report goes on to cite increases in profitability and decision-making outcome of up to 50%.

The reason for the increase in productivity and ROI is simple. Separating business rules from

programming code allows non-programmers to maintain business logic without writing code. Even for

the most talented developers, writing code is expensive and error prone (if you have any doubts

about this assertion, please see Test-Driven Development). The ability for interdependent team

roles to have a hand in business rule management naturally reduces the time, risk, and effort

inherent to programming changes to business rules in a vacuum. Shared business rule management

leads to reduced development schedules and lower maintenance costs.

In addition, extracting business rules and making them available to the wider team promotes

visibility and understanding of business policies and procedures, which serves to promote

consistent decision making which leads to profitability. Fair Isaac, a leading rule-based engine

vendor corroborates these assertions, reporting that in interviewing hundreds of customers

throughout the world, "a 25% compression of development time is quite common, along with cost

savings for developing new applications of up to 80% and maintenance of applications of up to 75%".

Another great benefit to isolating business rules is that it makes them eminently testable. This is

a core value that any Test-Driven Developer holds dear, and a business rules engine can be thought

of as a way to provide a different kind of dependency injection to your applications.

Introducing Microsoft Business Rules Framework

The Microsoft Business Rules Framework is a fully functional rule framework originally intended for

plugging in various rule executors and translators. The Microsoft Business Rules Engine is

Microsoft's implementation of their own rule language and corresponding translator components as

well as execution components based on the Rete algorithm (defined later) that plug in to the

Microsoft Business Rules Framework and is commonly referred to as the Microsoft Business Rules

Engine (BRE).

"

______________________________________________________________________________________________

A rule-based engine isolates business rules from the application making the rules eminently

reusable (and not to mention testable).

______________________________________________________________________________________________

"

While the Microsoft Business Rules Framework and BRE are still relatively new (both were originally

released with Microsoft BizTalk Server 2004), the Rete algorithm is not. The Artificial

Intelligence Journal published a paper by Dr. Charles L. Forgy in 1982 entitled "Rete: A Fast

Algorithm for the Many Pattern/Many Object Pattern Match Problem". Dr. Forgy first published his

research work on the Rete algorithm in 1974 as a an efficient pattern-matching algorithm which is

capable of evaluating rules at a very high rate of speed with little regard for the number of rules

being considered. The algorithm works by cross-checking a business fact with business policies to

determine which rules should be considered for execution. If a rule does not need to be considered,

it is skipped altogether. Also known as an inference-based rules engine, the Microsoft BRE also

supports forward chaining of business rules which causes the BRE to re-evaluate rules in a policy

when the action of a rule that has fired causes a change to the state of a fact that has otherwise

already been asserted.

Although the Microsoft Business Rules Framework (and MS BRE) ships with Microsoft BizTalk Server

2004, 2006, and 2006 R2, this is where any association to BizTalk Server ends. Microsoft defines

the Business Rules Engine as a stand-alone application that consists of a number of modules,

support components, and tools. What you get out of the box is Microsoft's implementation of

pluggable components which, in conjunction with the Business Rules Framework, is commonly referred

to as Microsoft BRE. The primary modules include the Business Rules Composer for constructing

policies, the Rules Engine Deployment Wizard for deploying policies created in the Business Rules

Composer, and the Run-Time Rule Engine that executes policies on behalf of a host application. I

will look at these modules in more detail as I apply a practical example of how to create a

business rule within a policy, and call it from a .NET application.

What it Isn't

As I mentioned before, the MS BRE has nothing to do with BizTalk Server. It ships and is installed

with BizTalk Server but you can take full advantage of MS BRE without BizTalk Server messaging or

orchestration. This means that if you choose to only install MS BRE on a machine, you can do so

with a very small footprint. However, keep in mind that since MS BRE is not a separate SKU, you can

only get it with BizTalk Server, and as such, you must meet licensing requirements for BizTalk

Server even if you only use MS BRE. While this may sound intimidating, doing any amount of market

research on competing rule-based engines will quickly prove that the price point in which Microsoft

places the Developer and Standard editions of BizTalk Server 2006 better makes MS BRE a compelling

choice for bringing a fully functional rules engine into the enterprise.

In addition, MS BRE has nothing to do with Windows Workflow Foundation (WF) Rules. While there are

similarities, it is important to understand that MS BRE is a product that is developed, maintained,

and supported by a different product team inside Microsoft. WF is not a product. WF is a framework

for building workflow enabled applications and services. WF supports the execution of business

rules; however, the features provided in WF Rules in the current shipping version of .NET 3.5 pale

in comparison to MS BRE. WF Rules lacks a rule editor that can be used outside of the developer

role and lacks a rule repository. Like most of the features in WF, this makes WF Rules a solid

starting point for building out additional rule-based engine functionality, but at its core merely

provides an engine which is capable of executing rules. In fact, in early drops of WF, WF workflows

were calling Microsoft BRE to demonstrate proof of concept scenarios before WF Rules were fully

baked. While Microsoft has not taken a position on the future of each offering, I can only

speculate that these competing offerings will converge, perhaps as part of the Oslo vision. Until

then, I believe, and others agree (please see sidebar "Comparing Microsoft BRE and WF Rules") that

MS BRE is a stronger choice for integrating rule-based engines into your applications and services.

Microsoft Business Rules Framework Architecture

The architecture for MS BRE is comprised of design-time and run-time components. As shown in Figure

1, design-time components that include the Business Rules Composer are provided via a separate user

interface (outside of Visual Studio) to manipulate the Vocabulary, Rule Store, and Rule Set object

model. While the BRE is a first-class citizen in BizTalk Orchestration, I will work exclusively

with the Business Rules Composer and Visual Studio 2008 to develop, test, and execute the rule set

in this article.

Click for a larger version of this image.

Figure 1: The Microsoft Business Rules Framework consists of design-time and run-time components.

Diagram courtesy of Microsoft Corporation.

The Vocabulary Object Model allows developers and business analysts to use the Business Rules

Composer to create domain-specific definitions for data, or facts that are represented in various

states.

The Rule Set object model allows for developers and analysts to build the rules that will consist

of raw facts that can be either XML message-based, any .NET object, or a field in a database table

or in-memory dataset. Rules are grouped according to business domain and are logically organized as

Policies. For example, you may have a rule that states that "If the customer is a preferred member,

always apply a 10% discount on the total checkout price". This rule might be just one rule in a

rule set that is logically represented as the discount policy for the company.

Once vocabularies and policies/rule sets are created, they need to be persisted to the Rule Store,

and the Business Rules Composer uses the Rule Store object model to do so. By default, the Rule

Store is a SQL Server database; however, it is possible to use a file or other backing store (with

some elbow grease, of course). Using SQL Server as the default repository for policies and

vocabularies has some obvious performance and management benefits. Rules and vocabularies are

serialized to BRL (Business Rules Language), which as you might imagine is an XML representation of

the policy and rules.

From a run-time perspective, an application, such as a Smart Client, Console, WCF Service, WF

application, or BizTalk Orchestration, works with a Policy class that provides the integration glue

with the BRE. The Policy works with an instance of the Rule Engine class, thus shielding the

developer and application from intimate details about the BRE itself.

The Rule Engine class is the workhorse behind the BRE and is responsible for the execution of the

business rule policies. The Rule Engine class takes a policy (rule set) name as an argument, along

with corresponding facts and determines which rules are applicable given the facts, translates the

rules from BRL to in-memory object graphs, and executes the appropriate rules. I will cover this in

more detail later, but it is important to understand that every rule has a condition, predicate,

and action. This means that given our now canonical rule ("If the customer is a preferred member,

always apply a 10% discount on the total checkout price"), if the rule executes, and the condition

in the rule evaluates to true, the 10% discount will be performed.

Finally, a Windows Service, known as the Rule Engine Update Service, monitors the Rule Store for

changes to rules or policies. If there is a change, the Rule Engine Update Service updates the Rule

Engine's local cache to ensure that Rule Engine instances that are bound to a live Policy instance

are updated in real time, and to also ensure that any subsequent Policy invocations use an instance

of the Rules Engine that is synchronized with the Rule Store.

The magic of the BRE is that it performs well because it is inference based. What this means is

that the BRE will only consider rules that apply to a given fact. Instead of looping through

dozens, hundreds, or thousands of rules, the BRE creates an agenda of rules to execute that are

associated with the fact. This could be a single rule or several. Once the rules are added to the

agenda, they are executed one by one until the execution cycle terminates. This means that you

might have one or several corresponding actions resulting in a number of rules firing. I'll cover

agenda and priority and provide an example of forward chaining towards the end of this article.

BRE Roles

As discussed, it takes much more than sheer programming to build a software product, and one of the

main objectives of the Microsoft Business Rules Framework is to help lubricate communication and

collaboration between team members in various yet intersecting roles. By using the Business Rules

Composer, all team roles can work together to implement the rules as part of a policy that makes

sense in a business context and is verifiable and traceable by all. While I will not go on a rant

about the merits of Domain Driven Design here, the power of sharing a common language and taxonomy

with your entire team is a tremendous boost to productivity, comprehension, and morale.

"

______________________________________________________________________________________________

Software product development teams also include stakeholders, line of business managers, business

analysts, and quality assurance analysts to name just a few.

______________________________________________________________________________________________

"

Once your rules and policies have been authored and tested, they can be deployed in a development

environment by anyone with access to the Business Rules Composer. However, in Staging and

Production environments it is likely that a release engineer or an administrative member of a

deployment team will be responsible for pushing out new policies and updated existing policies by

introducing a new policy version. This is precisely what the Deployment Utility is for.

Coming to Terms

I have already covered many of the following terms in this discussion, but let me provide some

precise definitions by example for clarity sake. Hopefully, after reading this article, you will be

well versed in the lingua franca that makes up the Microsoft Business Rules Framework.

Policy

A Policy is a versioned logical grouping of rules. It is represented by the Policy class, which

allows a calling component to execute a corresponding rule set that is bound to the policy. For

example, a discount policy would consist of rules about how and when to apply discounts to purchase

orders. You create a Policy using the Business Rules Composer, and execute a policy via the Policy

class. Policies are versioned, and once a version has been deployed, the policy is immutable. This

ensures that a policy version remains sacrosanct, and also supports concurrent policy versions.

Rule

A rule is a statement that consists of a condition and actions. Rules are commonly created within

the Business Rules Composer. A rule consists of a condition that evaluates facts and a

corresponding action to take if the condition evaluates to true. If the preferred member condition

is met, then the corresponding action will be to apply a 10% discount to the purchase. It is

possible to program directly with the Rule class, but in this article you will build rules using

the Business Rules Composer and execute rules by using the Policy class.

Condition

A condition simply consists of predicates that apply to a fact, and always returns true or false.

Examples of predicates are between, greater than, less than, equal to, etc.

Facts

Fundamentally, a fact is in-memory data that is acted upon within the BRE. For example, a Customer

object is a memory type that contains information about a customer. The information is represented

as public properties, such as First Name, Last Name, and Preferred Member. These fields are

referred to as "fact slots" which are then used in conjunction with a condition and action to form

a rule. In the example, the "preferred member" fact would map to the Preferred Member fact slot on

the Customer fact.

Fact Types

There are actually two types of facts. Short-term facts are passed into the Policy object and

removed from memory as soon as a policy completes execution. Short-term facts are introduced to the

Policy class as .NET objects, XML document instances, or database rowsets. Long-term facts remain

in memory across multiple execution cycles. An example of a short-term fact might be the Customer

instance passed into the Policy instance, while a long-term fact might be the standard shipping

rate to apply. Since the standard shipping rate seldom changes, this is an excellent candidate for

a long-term fact, which is cached in memory to be reused throughout rule-engine execution cycles.

In addition, long-term facts can be configured to refresh cache as necessary.

Actions

An action is the consequence of a rule being executed within a policy that yields a true condition

evaluation. The action results in a function call that is wired up within the Rules Engine

Composer. For example, given a customer who is a preferred member, the action may be to set the

Discount Percentage field on the Customer fact itself. This is just one of several possible

actions.

Vocabulary

A vocabulary is simply a set of user friendly business definitions in the language of the domain

that map to a fact or fact slot. For example, the preferred member status of a customer may be

represented in SQL as "SELECT MembershipStatus from Customers WHERE LastName= "Deniro". While this

statement may be pretty straightforward, for non-developers, the T-SQL syntax may not be as

intuitive. You can use a vocabulary to define the fact and give it a friendly name such as

"MemberStatus". Now developers and non-developers can have domain-specific conversations in

building a business rule around pricing models for customers who are members.

Installing and Working with the Microsoft Business Rules Engine

Please don't let the fact Microsoft BRE ships with BizTalk Server intimidate you. While BizTalk

Server is indeed a robust server platform that requires experience to install and configure, the

installer for BizTalk Server 2006 and later has been significantly streamlined compared to previous

versions, and installing the Business Rules Engine is very straightforward.

"

______________________________________________________________________________________________

Up to 70% of CIO budgets are spent on maintenance.

______________________________________________________________________________________________

"

In fact, as you'll learn below, you can install the BRE completely independently of other BizTalk

components, making installation a breeze:

1. Simply start the BizTalk Server 2006 or 2006 R2 installer and click "Install Microsoft BizTalk

Server on this computer" as shown in Figure 2.

2. On the Component Installation screen, clear all options except "Documentation" and "Business

Rules Components", and then click Next as shown in Figure 3.

3. As shown in Figure 4, you will see a Summary screen that summarizes the fact that you are only

installing documentation and core components necessary for the BRE. Click "Install" to begin

installation.

4. After a few moments, you will be presented with an Installation Progress screen which will take

a couple of minutes to complete. Once complete, you will be presented with a corresponding

screen as shown in Figure 5. Make sure to check "Launch BizTalk Configuration" and click Finish

to begin configuring BRE.

5. The BizTalk Server 2006 configuration screen appears. As shown in Figure 6, make sure to select

"Basic configuration", confirm the name of the machine on which you are performing the

installation/configuration, and enter credentials that will be used to run the Rule Engine

Update Service. Click Configure, and you should see a list of components identical to Figure 7.

6. Click Next and, in a few moments, configuration should complete and succeed as shown in Figure

8.

Click for a larger version of this image.

Figure 2: To install Microsoft BRE, simply launch the BizTalk Server installer.

Click for a larger version of this image.

Figure 3: Installation of the Microsoft BRE and corresponding Business Rules Framework simply

consists of selecting the Business Rules Components option.

Click for a larger version of this image.

Figure 4: The Microsoft Business Rules Framework is installed automatically by selecting the

Business Rules Components. These are the only components required to begin using Microsoft BRE

immediately; however, the product documentation is also recommended.

Click for a larger version of this image.

Figure 5: Following installation, it is necessary to configure the Microsoft BRE components.

Click for a larger version of this image.

Figure 6: Configuration is very simple and only requires a host name and account credentials for

the Rule Engine Update Service.

Click for a larger version of this image.

Figure 7: The Summary lists the components that will be configured.

Click for a larger version of this image.

Figure 8: The Microsoft BRE is installed successfully in a matter of minutes.

A gentle reminder: Please remember that although the Microsoft Business Rules Framework and BRE

components are fully functional in a standalone configuration, any machine running BRE, or any

other BizTalk Server components must be fully licensed for BizTalk Server 2006 or better.

With the Microsoft Business Rules Framework, and Microsoft Business Rules Engine installed, you are

ready to create your first policy!

Creating and Deploying a Policy with the Business Rules Composer

I am going to continue working with the same business rule I've used in previous discussions.

Without knowing anything about the business domain, by simply reading the rule in plain English, it

is evident that I am dealing with a customer and purchase domain.

"

______________________________________________________________________________________________

According to IDC, three-year net ROI for organizations deploying rule-based engines is in excess of

100% through 25%-80% reductions in development costs.

______________________________________________________________________________________________

"

Both of these entities are fundamental for composing the business rule and for BRE execution,

because the rule must first determine if the customer is a preferred member, and if so, apply a 10%

discount to the purchase order.

Figure 9 shows a model of the Customer and PurchaseOrder entities, and the code for each entity is

provided in Listing 1 and Listing 2 respectively. Recall that the BRE can work with XML, a database

or .NET objects, and in this case, since I am modeling the domain by using C# classes as my domain

entities, I will simply use these same objects when working with the BRE.

Click for a larger version of this image.

Figure 9: The Customer and Purchase Order business entities are used to model the business domain.

The sample code that I've prepared for this article (please refer to sidebar "Solution Download"

for download instructions) contains three projects:

1. Acme.RetailOperations: Represents the application or process layer of a sample application.

2. Acme.BusinessEntities: Contains the Customer and PurchaseOrder entities previously discussed.

3. Acme.RetailOperations.Tests: Contains unit tests that allow us to emergently build our

application layer.

4. Once you download the solution, I would encourage you make a copy of the MSBRESample.zip file,

unzip it, open the MSBRESample.sln and delete the contents of the PurchaseService.cs file in

the Acme.RetailOperations project as well as the contents of the PurchaseServiceTests.cs file.

There isn't much code to write, but I want to show you how powerful Test-Driven-Development

coupled with the Microsoft Business Rules Engine can be in not only decoupling the business

rules from your application layer, but also in writing just enough code to get the job done.

5. I have also provided all code listings, so you should also be able to follow along without

firing up Visual Studio.

6. First, I'll write a test method to exercise the application for correctly adhering to the 10%

discount rule for customers with a preferred membership status.

7. I stubbed out the following test method called

"ExecuteCustomerCheckOutDiscountAmountShouldBeTenPercent". The name of the test method tells me

two things: First, I am exercising the CustomerCheckOut method on the PurchasingService, and

second, I expect that the DiscountAmount property on the customer instance is 10% as shown in

Listing 3 which provides the unit test code

Of course, when I try to compile my Acme.RetailOperations.Tests project, I get a bunch of

compilation errors because the CustomerCheckOut method doesn't exist yet.

Pop into the empty PurchaseService class and write enough code to at least get the unit test to

compile. Listing 4 shows the contents of my very primitive CustomerCheckout method implementation,

but remember, the goal at this point is to write just enough code to compile the unit test as shown

below:

namespace Acme.RetailOperations

{

public class PurchaseService

{

public void CustomerCheckout(Customer customer)

{

// some logic

}

}

}

At this point, the unit test compiles but if you run it, it should fail because in setting up the

Customer and PurchaseOrder within the unit test, I've initialized the DiscountPercentage to 0%.

Despite the PreferredMember property being set to true, there is no business rule or policy for

acting on this (the body of the CustomerCheckout method is empty), and as expected, the test fails

as shown in Figure 10.

Click for a larger version of this image.

Figure 10: The unit test fails because the Microsoft BRE policy has not yet been integrated into

the application layer.

The goal now is to write enough code to get the test to pass. In order for the test to pass, you

need to enforce the business rule, and you'll use the Microsoft BRE to do just that.

Start the Business Rules Composer by going to Start > Program > Microsoft BizTalk Server 2006 >

Business Rule Composer as shown in Figure 11. In the upper left-hand corner, you will find the

Policy Explorer. Right-click the Policy root and click "Add New Policy" as shown in Figure 12.

Provide a name for the policy that is intuitive and representative of the business domain, such as

"Customer Discounts Policy". As shown in Figure 13, you will notice that the Policy has been

automatically versioned to 1.0. Right-click the version, select "Add New Rule", and name the rule

"Preferred Member Customer Discount".

Click for a larger version of this image.

Figure 11: The Business Rules Composer is started from the Microsoft BizTalk Server 2006 program

group.

Click for a larger version of this image.

Figure 12: Adding a new policy allows you to group business roles according to domain-specific

groups.

Click for a larger version of this image.

Figure 13: Once a new policy is created, it is versioned and cannot be changed once deployed to the

repository.

On the right pane is a surface area on which to build your condition. As you might imagine, this is

simply an "If" statement with some predicates. Select the "Equal" predicate as shown in Figure 14.

You will use the equality predicate to determine if the customer is a preferred member.

Click for a larger version of this image.

Figure 14: The equality predicate is just one of several predicates for building conditional

business rules within the Business Rules Composer.

To do so, you need to tell the BRE which fact slot will contain the data that determines if the

customer is a member, so under Fact Explorer, click the .NET Class tab, right-click ".NET

Assemblies", and click Browse. As shown in Figure 15, a list of assemblies appears. The list is an

enumeration of the assemblies in the Global Assembly Cache, which is a requirement for .NET objects

that will be used as facts (if you have not already done so, add the Acme.BusinessEntities.dll

assembly to the GAC prior to browsing for it). Select the Acme.BusinessEntities.dll and click OK.

Click for a larger version of this image.

Figure 15: Assemblies containing facts to be asserted must be added to the Global Assembly Cache

(GAC).

Both Customer and PurchaseOrder classes are enumerated under the ".NET Assemblies" root, and if you

expand the Customer class, you will find assessors for all public properties, including the

PreferredMember property as shown in Figure 16. Drag the PreferredMember get accessor to the

Condition surface area and drop onto Argument 1. The condition should now look like Figure 17. Now,

click "Argument 2" and type "true" without the quotes as shown in Figure 18. You now have a full

condition that inspects the PreferredMember fact slot on the Customer fact and tests the value for

equality to true. Recall that a condition will always result in a Boolean value.

Click for a larger version of this image.

Figure 16: Facts consist of fact slots, which in the case of .NET types include assessors for

working with the fact.

Click for a larger version of this image.

Figure 17: An equality predicate requires two arguments. The first argument is provided by dragging

and dropping the corresponding fact slot from the Customer fact.

Click for a larger version of this image.

Figure 18: A condition is simply an If/Then statement that will always result in true or false.

With the condition complete, all that is left is to provide the BRE with an action to execute when

the condition is true. In this case, you simply want to set the DiscountPercentage property on the

PurchaseOrder fact to 10%. Drag the DiscountPercentage set accessor from the PurchaseOrder fact and

drop it on the Actions design surface. Figure 19 shows the compete rule with conditions and

corresponding action that should fire if the condition evaluates to true.

Click for a larger version of this image.

Figure 19: A business rule is the combination of the condition and action should the condition

evaluate to true.

Note that creating vocabulary definitions are useful for creating friendly names for otherwise

esoteric facts and fact slots. For example, if you are using an XML message as a fact and have a

complex XPath query to map a condition argument to a fact slot, you may quickly defeat the purpose

of exposing your rules in a way that supports inter-role collaboration. The solution to this

dilemma is to create vocabulary definitions that act as aliases for fact slots that would otherwise

be unreadable to the non-developer (even I detest reading XPath statements!). Since you are using

.NET types that are modeled after the business domain, I have skipped creating vocabulary

definitions altogether.

"

______________________________________________________________________________________________

If there are two or more rules that use the same fact slot in the condition, the BRE will determine

execution order based on priority.

______________________________________________________________________________________________

"

At this point, you have successfully created the "Preferred Member Customer Discount" rule within

the "Customer Discounts Policy" policy. Right-click the policy and save the rule.

Recall that a policy can contain one or more rules, and as such the policy is the logical unit of

deployment. Also recall that policies are versioned and once a policy has been deployed, it is

immutable. Therefore, before you publish and deploy the policy, you need to test it.

Testing a Policy by Implementing the IFactCreator Interface

As I've discussed, at run time, each of these facts and fact slots will be asserted into the BRE

and the BRE will determine which rule(s) to add to its agenda based on the presence of facts. For

testing purposes, it is necessary to provide the Business Rules Composer with a hydrated instance

of the Customer object which it will use to determine which rules should be added to the agenda. To

hydrate an instance, you must first create what is called a "Fact Creator".

"

______________________________________________________________________________________________

Dr. Forgy first published his research work on the Rete algorithm in 1972 as an efficient

pattern-matching algorithm which is capable of evaluating rules at a very high rate of speed.

______________________________________________________________________________________________

"

Creating a Fact Creator is extremely straightforward, and simply entails implementing the

IFactCreator interface on a class to provide a surrogate Customer class to the BRE using a

prescribed interface.

The CustomerFactCreator class, shown in Listing 5 shows the implementation of the IFactCreator. The

CreateFacts method fulfills a contract to return an array of objects. These objects are the facts

that are used by the BRE to conduct a pre-deployment test. In this case, I have simply copied and

pasted the Customer and PurchaseOrder initialization code from the unit test to the CreateFacts

method, created a single dimension array to hold the Customer instance, and fulfilled the contract

by returning the array.

With the Acme.BusinessEntities.dll in the GAC, right-click "Version 1.0" of the Customer Discounts

Policy, and then select "Test Policy" as shown in Figure 20. A screen appears which allows you to

select the CustomerFactCreator. Click "Add", select the Acme.BusinessEntities.dll from the list of

.NET assemblies, and then click "OK". The Business Rules Composer will query the assembly for any

Fact Creators and enumerate them. As shown in Figure 21, select the CustomerFactCreator and click

"OK".

Click for a larger version of this image.

Figure 20: The Business Rules Composer includes an integrated tool for testing condition behavior

and agenda plan.

Click for a larger version of this image.

Figure 21: A Fact Creator must be supplied to the Business Rules Composer testing tool to assert

the required facts for execution.

Now click "Test". Immediately, the agenda results are displayed in the test output pane as shown in

Figure 22.

Click for a larger version of this image.

Figure 22: Agenda results are output immediately following the assertion of test facts into the

BRE.

Understanding Agendas and Priority

Now I want to look at the test results of the Customer Discounts Policy test by reviewing the

agenda results in Figure 22.

You used the CustomerFactCreator to assert the Customer instance as a fact to the BRE. The BRE then

looked for any rules that contain conditions which map to fact slots that are present in the fact

that was asserted. Because the Customer indeed contains a field which indicates if the sample

customer is a preferred member, the rule was added to the agenda and executed. The condition

evaluated to true, because the PreferredMember fact slot on the Customer fact was set to true in

your CustomerFactCreator. Since the Customer was asserted as a short-term fact, and there are no

other rules in the policy, the Customer instance is removed from memory and the BRE execution cycle

terminates.

If there are two or more rules that use the same fact slot in a condition, the BRE will determine

execution order based on priority. Priority is set on each rule within the Business Rule Composer.

A rule with a higher priority fires first.

This has been a good test for testing that the condition of your rule is behaving as expected, and

that the agenda is loading rules according to the expected priority, but you still don't know if

the action is working as designed. There is no good way to do this within the Business Rules

Composer.

Fortunately, you have a unit test in your Visual Studio solution that is up for the job!

Calling a Policy Programmatically

With the test complete, right-click Version 1.0 of the policy, click "Publish", and then click

"Deploy" to deploy the policy to the repository as shown in Figure 23. You will notice that you can

no longer modify the policy by editing existing rules, removing rules, or adding new ones. Since

the policy has been deployed, you cannot change it without creating a new version of the policy.

Click for a larger version of this image.

Figure 23: Policies can be deployed to the repository directly from the Business Rules Composer or

using the BRE Deployment Utility (not shown).

Recall that although your ExecuteCustomerCheckOutDiscountAmountShouldBeTenPercent unit test

compiles (Listing 3), the last time you exercised it, it failed. It failed because there is no

implementation to the CustomerCheckOut method skeleton and therefore, the DiscountPercentage is

zero just as it was before the test ran.

"

______________________________________________________________________________________________

The Rule Set object model allows for developers and analysts to build the rules that will consist

of raw facts, which can be either XML message-based, any .NET object, or a field in a database.

______________________________________________________________________________________________

"

Jumping back into Visual Studio, in the Acme.RetailOperations project, right-click References and

add a reference to the Microsoft.RulesEngine.dll which contains everything that you need to

integrate the Microsoft BRE into your application. The Microsoft.RuleEngine.dll assembly resides in

the C:\Program Files\Microsoft BizTalk Server 2006\ folder as shown in Figure 24.

Click for a larger version of this image.

Figure 24: Programming with the Microsoft BRE is as simple as adding a reference to the

Microsoft.BusinessRules.dll assembly.

I want to focus on the enforcement of the business rule, so I am not going to spend any time on

other implementation details. You certainly might expect the CustomerCheckOut method to carry out

additional chores such as checking inventory, calculating shipping charges, and authorizing a

credit card.

With the reference to the Microsoft.RulesEngine.dll added, add the following using statement to the

PurchaseService.cs file:

using Microsoft.RuleEngine;

Listing 4 shows the contents of the PurchaseService class, which will act as your primitive

application layer.

You need to split the Customer and PurchaseOrder out into two separate facts because the BRE will

work with each fact separately. You can accomplish this by simply creating an object array and

adding the Customer instance and decomposed PurchaseOrder instance to the fact array.

With the facts ready, simply instantiate a Policy and provide the name of the policy you are

working with in the constructor. Note that you can also provide a specific version of the policy,

but if omitted, the newest policy will always be used. Now, call Execute on the Policy instance and

pass in the facts array.

When the BRE is done executing the policy, it will set the DiscountPercentage property on the

instance of the Customer class to 10% which the PurchaseService maintains a reference to. Now,

re-run the ExecuteCustomerCheckOutDiscountAmountShouldBeTenPercent unit test and it should pass

with flying colors as shown in Figure 25.

Click for a larger version of this image.

Figure 25: Once the BRE policy is integrated into the application layer, unit tests are critical to

ensuring corresponding actions behave as expected.

While this is a very simple implementation of a purchasing application layer, the loose coupling

between the application layer and the business rules is powerful indeed. Not only is there less

code to write (you've harnessed the power of a fully featured rule-based engine with two lines of

code), the discount policy is free to evolve with the needs of the business.

Suppose a decision was made to increase or decrease the discount amount for preferred members, or

to eliminate the rule altogether? Affecting this change would simply be a matter of updating the

Customer Discounts Policy within the Business Rules Composer, testing the condition, and deploying

a new policy version, all without changing a single line of code!

Understanding Forward Chaining

I have (hopefully) kept things relatively simple, and by now you should have a good understanding

of the Microsoft Business Rules Framework and BRE fundamentals. One topic I have not talked about

in detail is forward chaining.

"

______________________________________________________________________________________________

The Rule Engine class takes a policy (rule set) as an argument and determines which rules are

applicable given the facts, translates the rules from BRL to in-memory object graphs, and executes

the appropriate rules.

______________________________________________________________________________________________

"

Suppose your company introduced a new business rule that ensures that the combination of the

preferred member discount and any current sale discounts do not cause the final price to fall below

margin. This is important to ensure that the preferred membership program doesn't inadvertently

cost the company money.

Such a business rule might be: "If the discount percentage on an order would cause the unit price

to fall below margin, adjust the discount percentage accordingly."

While it may sound complex at first, it is really very simple. The only time this rule needs to be

considered is when a discount percentage is present. Non-preferred customers rarely have discounts

unless they use a discount code.

The Customer Discounts Policy would prioritize the existing rules such that the 10% discount rule

fires first, and upon the Discount Percentage fact slot being updated, the margin protection rule

would be considered. If the customer receives no discount, the Discount Percentage remains null;

however, if the fact changes as a result of a preceding rule, new rules must be considered. This

means that the BRE would complete two cycles. The second cycle would fire as a result of the

Discount Percentage fact being changed and thus a forward chaining of execution.

Summary

I have provided an overview of rule-based engine technology and Microsoft's implementation within

the Microsoft Business Rules Engine which is based on the Microsoft Business Rules Framework.

You took an emergent approach to building the customer check out functionality in your sample

application by using Visual Studio 2008 and test-first development. You worked with the Business

Rules Composer to create a policy and a rule, and tested the policy before deploying it to the Rule

Repository.

You then leveraged the .NET Microsoft BRE API to integrate the policy you created and verified the

correct behavior by running your unit test within Visual Studio.

While one of the strengths of implementing a rule-based engine is the ease of working with and

deploying rules, it is very important to understand that a rule-based engine such as Microsoft BRE

does not eliminate the need for strong application lifecycle management policies. While team and

organizational productivity will increase significantly by leveraging the BRE, the fact that

business rules can be updated with ease can also be a dangerous thing.

Organizations that effectively leverage a rule-based engine like Microsoft BRE have likely evolved

to a higher level of thinking that makes rule management service-oriented. The decoupling and

isolation of rules and policies from constituent applications fixes many old problems, but also

introduces new challenges around change management because a change in one rule can have widespread

organizational impact depending on the number of applications that integrate with the given policy.

For this reason, it is critical to maintain development, integration, and testing environments for

integrating rule changes-nothing changes here.

As an added bonus, if you and your team practice test-driven development, regression testing a

policy change should be as simple as running corresponding batteries of unit tests manually or in

the next automated build. While not a silver bullet, this is definitely one step forward in

increasing business and IT alignment because the rules are centralized, transparent, and support

flexible applications that are not only ready for change, but built for it!

"

______________________________________________________________________________________________

You can install the BRE completely independently of other BizTalk components, making installation a

breeze!

______________________________________________________________________________________________

"

One final word of advice: It is very important to understand that despite the compelling

productivity improvements that deploying Microsoft BRE will bring, I do not recommend embarking on

a project whose sole purpose is to integrate a rule-based engine within the enterprise. Such a

project is doomed to fail because technology projects for technology's sake rarely provide

convincing evidence that there is value in the undertaking in and of themselves. The key with any

software or IT project is to focus on delivering business value. Services, SOA, and high-performing

rule engines like Microsoft BRE are merely a vehicle for doing so. Don't confuse the two.

The CHAOS report (see sidebar) finds that 13% of features in an application are often used, and 7%

of features are always used. My advice to you is to work with the business members of your team to

identify the 30% sweet spot and start with a business process or business rule or two. By taking a

middle-out approach, you are bound to quickly and easily find processes for which introducing this

flexibility would add significant business value. Think big, start small, prove your business case

and the rest will follow.

Rick Garibay

&

[ArticleImage.aspx?QuickID=0811071&MaxWidth=150&Image=author:5a9ce65b-d576-4b28-9b47-6e569e

b3bab8]

By: Rick Garibay

With over 13 years' experience delivering solutions on the Microsoft platform across industry

sectors such as finance, transportation, hospitality and gaming, Rick is a developer, architect,

speaker and author on distributed technologies and is the General Manager of the Connected Systems

Development Practice at Neudesic.

Rick specializes in distributed technologies such as Microsoft .NET, Windows Communication

Foundation, Workflow Foundation, and Windows Azure to deliver business value and drive revenue

while reducing operational costs.

Rick serves as a member of the Microsoft Application Platform Partner Advisory Council and is an

advisor to Microsoft in a number of capacities including long-time membership on the Business

Platform and Azure Technology Advisors group. As a five-time Microsoft Connected Systems MVP, Rick

is an active speaker, writer and passionate community advocate in the national .NET community. Rick

is the Co-Founder of the Phoenix Connected Systems User Group, celebrating four years in operation.

Recent presentations include talks at the Microsoft SOA and Business Process Conference in Redmond,

WA, Microsoft TechEd, DevConnections, .NET Rocks, Desert Code Camp, and numerous Microsoft events

throughout North America. Rick is a frequent contributor to industry publications such as CODE

Magazine, and is the co-author of Windows Server AppFabric Cookbook by Packt Press.

When not immersed in the work he loves, Rick enjoys mountain biking and spending time with his

wife, Christie and two children, Sarah and Ricky.

Fast Facts

A business rule is a statement that defines or constrains some aspect of the business. It is

intended to assert business structure or to control or influence the behavior of the business.

Emergent Development

Scott W. Ambler presents some compelling facts about the inevitability of change in our software

applications: http://www.agilemodeling.com/essays/examiningBRUF.htm

Comparing Microsoft BRE and WF Rules

Perhaps one of the most knowledgeable rule-engine enthusiasts on the planet, Charles Young has

written several articles about the Microsoft Business Rules Framework, Microsoft BRE, and Workflow

Rules.

You can learn about the performance benefits of Microsoft BRE along with strengths and liabilities

of each offering and much more by visiting Charles's blog:

http://geekswithblogs.net/cyoung/archive/2007/08/12/114597.aspx

MSDN Documentation

Complete documentation for the Microsoft BRE is available on the MSDN Network:

http://msdn.microsoft.com/en-us/library/aa577691.aspx

On the Rete Algorithm

More information regarding the Rete algorithm is available on the PST Web site:

http://www.pst.com/rete2.htm

Solution Download

You can download the code for this article at http://rickgaribay.net/

______________________________________________________________________________________________

Click here for a text-only version of this listing. Listing 1: The Customer Domain Entity.

using System;

using System.Text;

namespace Acme.BusinessEntities

{

/// <summary>

/// Encapsulates elements used to describe a customer.

/// </summary>

public class Customer

{

private string m_FirstName;

private string m_LastName;

private bool m_PreferredMember;

private PurchaseOrder m_Order;

public string FirstName

{

get { return m_FirstName; }

set { m_FirstName = value; }

}

public string LastName

{

get { return m_LastName; }

set { m_LastName = value; }

}

public bool PreferredMember

{

get { return m_PreferredMember; }

set { m_PreferredMember = value; }

}

public PurchaseOrder Order

{

get { return m_Order; }

set { m_Order = value; }

}

}

}

Click here for a text-only version of this listing. Listing 2: The Purchase Order Domain Entity.

using System;

using System.Text;

namespace Acme.BusinessEntities

{

/// <summary>

/// Encapsulates elements used to describe a purchase order.

/// </summary>

public class PurchaseOrder

{

private string m_PurchaseOrderId;

private int m_TotalItems;

private decimal m_TotalPurchaseAmount;

private float m_DiscountPercentage;

private decimal m_ShippingCost;

private decimal m_TotalIncludingShipping;

public string PurchaseOrderId

{

get { return m_PurchaseOrderId; }

set { m_PurchaseOrderId = value; }

}

public int TotalItems

{

get { return m_TotalItems; }

set { m_TotalItems = value; }

}

public decimal TotalPurchaseAmount

{

get { return m_TotalPurchaseAmount; }

set { m_TotalPurchaseAmount = value; }

}

public float DiscountPercentage

{

get { return m_DiscountPercentage; }

set { m_DiscountPercentage = value; }

}

public decimal ShippingCost

{

get { return m_ShippingCost; }

set { m_ShippingCost = value; }

}

public decimal TotalIncludingShipping

{

get { return m_TotalIncludingShipping; }

set { m_TotalIncludingShipping = value; }

}

}

}

Click here for a text-only version of this listing. Listing 3: The PurchaseServiceTest Unit Test

Class.

using System;

using System.Text;

using Microsoft.VisualStudio.TestTools.UnitTesting;

using Acme.BusinessEntities;

using Acme.RetailOperations;

namespace Acme.RetailOperations.Tests

{

[TestClass]

public class PurhaseService

{

public PurhaseService()

{

//

// TODO: Add constructor logic here

//

}

private TestContext testContextInstance;

public TestContext TestContext

{

get

{

return testContextInstance;

}

set

{

testContextInstance = value;

}

}

[TestMethod]

public void ExecCustomerCheckOutDiscAmtShouldBeTenPercent()

{

Customer customer = new Customer();

customer.FirstName = "Robert";

customer.LastName = "Deniro";

customer.PreferredMember = true;

PurchaseOrder order = new PurchaseOrder();

order.DiscountPercentage = 0f;

customer.Order = order;

PurchaseService service = new PurchaseService();

service.CustomerCheckout(customer);

Assert.IsTrue(customer.Order.DiscountPercentage == .10f, "Expected .10 but was {0}",cus

tomer.Order.DiscountPercentage);

}

}

}

Click here for a text-only version of this listing. Listing 4: The PurchaseService Application

Layer.

using System;

using System.Text;

using Acme.BusinessEntities;

using Microsoft.RuleEngine;

namespace Acme.RetailOperations

{

/// <summary>

/// Provides purchase ordering functionality and integrates with BRE.

/// </summary>

public class PurchaseService

{

public void CustomerCheckout(Customer customer)

{

object[] facts = new object[2];

PurchaseOrder order = customer.Order;

// some logic

// Determine any discounts

Policy policy = new Policy("Customer Discounts Policy");

policy.Execute(facts);

customer.Order = order;

// some additional logic

}

}

}

Click here for a text-only version of this listing. Listing 5: The CustomerFactCreator Class.

using System;

using System.Text;

using Microsoft.RuleEngine;

namespace Acme.BusinessEntities

{

/// <summary>

/// Implements the IFactCreator interface for providing .NET types to the BRE for testing purpo

ses.

/// </summary>

public class CustomerFactCreator : IFactCreator

{

#region IFactCreator Members

public object[] CreateFacts(RuleSetInfo ruleSetInfo)

{

object[] facts = new object[1];

Customer customer = new Customer();

customer.FirstName = "Robert";

customer.LastName = "Deniro";

customer.PreferredMember = true;

PurchaseOrder order = new PurchaseOrder();

order.DiscountPercentage = 0f;

customer.Order = order;

facts[0] = customer;

return facts;

}

public Type[] GetFactTypes(RuleSetInfo ruleSetInfo)

{

throw new NotImplementedException();

}

#endregion

}

}