Programming with the Microsoft Business Rules Framework

Programming with the Microsoft Business Rules Framework

usiness 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 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.

A Little Background
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.

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.

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.”

As a practical example, a business rule might read like this:

“If the customer is a preferred member, always apply a 10 percent discount on the total checkout price.”

Take a moment and re-read the Business Rule Group’s definition above. Using that perspective, the significance of this rule is profound. Even with very little specific knowledge about this business, it’s evident that:

  • The company sells products or services to individuals.
  • Elite customers who hold a membership status are entitled to receive a 10 percent discount on purchases.

This rule is likely part of an organizational customer loyalty and marketing strategy, because 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 make higher-dollar purchases, because they’ll get a modest discount.

This is only one example. Think about the business rules that govern the applications you’ve 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. Further, 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.

Still, 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 let you 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.

Editor’s Note: This article was first published in the November/December 2008 issue of CoDe Magazine, and is reprinted here by permission.

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, while also allowing disparate applications to consume the rules in a managed, service-oriented manner. As such, most rule-based engines provide a rule editor, which lets people 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 predecessors 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 two-tier, n-tier, and service-oriented architecture.

The industry has widely accepted that it’s best practice to separate the data layer from the business layers.

The industry, in building scalable systems that are also maintainable, has widely accepted separating the data layer from the business layers as best practice. 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. 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 behind decoupling is that the less one component or service knows about the other, the more each component or service is free 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. Because 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.

Software product development teams also include stakeholders, line of business managers, business analysts, and quality assurance analysts, to name just a few.

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 comprised not just of developers and architects; software product development also 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 percent of CIO budgets are spent on maintenance. Even conservatively, if you assume that half the maintenance costs are attributable to business rules maintenance, it is likely that upward of 35 percent of IT budgets gets 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 percent through 25-80 percent reductions in development costs. The report goes on to cite increases in profitability and decision-making outcome of up to 50 percent.

According to IDC, three-year net ROI for organizations deploying rule-based engines is in excess of 100 percent through 25-80 percent reductions in development costs.

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 in turn leads to increased profitability. Fair Isaac, a leading rule-based engine vendor, corroborates these assertions, reporting that in interviewing hundreds of customers throughout the world, ?a 25 percent compression of development time is quite common, along with cost savings for developing new applications of up to 80 percent and maintenance of applications of up to 75 percent.”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. You can think of a business rules engine 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 (BRE) is Microsoft?s implementation of their rule language and corresponding translator components, as well as execution components based on the Rete algorithm (defined later). The BRE plugs into the Microsoft Business Rules Framework.

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.

Rete is an efficient pattern-matching algorithm 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.

Dr. Forgy first published his research work on the Rete algorithm in 1974 as an efficient pattern-matching algorithm capable of evaluating rules at a very high rate of speed.

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 BRE as a stand-alone application consisting of a number of modules, support components, and tools. 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. You’ll see more detail later, using a practical example of how to create a business rule within a policy, and call it from a .NET application.

See also  Comparing different methods of testing your Infrastructure-as-Code

What It Isn’t
Although MS BRE ships and installs with BizTalk Server, it’s separate. You can take full advantage of MS BRE without BizTalk Server messaging or orchestration. This means that if you choose to install only MS BRE on a machine, you can do so with a very small footprint. However, keep in mind that because MS BRE is not a separate SKU, you can get it only with BizTalk Server, and therefore, 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 for the Developer and Standard editions of BizTalk Server 2006 makes MS BRE a compelling choice for bringing a fully functional rules engine into the enterprise.

Author’s Note: 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.

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 it lacks a rule repository. Like most of the features in WF, this makes WF Rules a solid starting point for building additional rule-based engine functionality, but at its core, WF merely provides an engine 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, see the useful links at the end of this article) 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 composed of both design-time and run-time components. As shown in Figure 1, the design-time components (such the Business Rules Composer) are provided via a separate user interface that runs outside of Visual Studio. These design-time components manipulate the Vocabulary, Rule Store, and Rule Set object model. While the BRE is a first-class citizen in BizTalk Orchestration, you’ll see how to work exclusively with the Business Rules Composer and Visual Studio 2008 to develop, test, and execute the rule set in this article.

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

The Vocabulary Object Model lets developers and business analysts use the Business Rules Composer to create domain-specific definitions for data or facts represented in various states.

The Rule Set object model lets developers and analysts build the rules, which consist of raw facts that can be either XML message-based, .NET objects, 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, the earlier rule “If the customer is a preferred member, always apply a 10 percent discount on the total checkout price” might be just one rule in a rule set logically represented as the discount policy for the company.

Vocabularies and policies/rule sets need to be persisted to the Rule Store. The Business Rules Composer uses the Rule Store object model for persistence. 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.

Rules built with the Rule Set object consist of raw facts, which can be either XML message-based, .NET objects, or fields in a database.

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, a predicate, and an action. This means that given our now canonical rule (“If the customer is a preferred member, always apply a 10 percent discount on the total checkout price”), if the rule executes, and the condition in the rule evaluates to true, the 10 percent 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. When a change occurs, the Rule Engine Update Service updates the Rule Engine?s local cache to ensure that Rule Engine instances bound to a live Policy instance are updated in real time, and also ensure that any subsequent Policy invocations use an instance of the Rules Engine synchronized with the Rule Store.

The magic of the BRE is that it performs well because it is inference based?the BRE will consider only 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. After adding the rules to the agenda, it executes them 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 toward the end of this article.

BRE Roles
As discussed, it takes much more than sheer programming to build a software product. 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 which 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.

After authoring and testing, rules and policies 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 briefly covered many of the following terms in this discussion, but here are some more precise definitions for clarity’s sake. After reading this article, you should 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 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; after a version has been deployed, the policy is immutable. This ensures that a policy version remains sacrosanct, and also enables support for 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. In the canonical example, when the preferred member condition is met, the corresponding action will be to apply a 10 percent 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. Evaluating a condition always returns true or false. Examples of predicates are between, greater than, less than, equal to, and so on.
  • Facts: Fundamentally, a fact is in-memory data 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. In rule terms, 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. In addition, long-term facts can be configured to refresh the 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 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, in SQL, SELECT MembershipStatus from Customers WHERE LastName= “Deniro” might represent the preferred member status of a customer. While this concept may be pretty straightforward, the T-SQL syntax may not be as intuitive for non-developers. You can use a vocabulary to define the fact and give it a friendly name such as MemberStatus. Now both 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
Don’t let the fact Microsoft BRE ships with BizTalk Server intimidate you. While BizTalk Server is 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, so installing the Business Rules Engine is very straightforward.

In fact, as you’ll learn below, you can install the BRE completely independently of other BizTalk components, making installation a breeze:

    Figure 2. Installer Screen: To install Microsoft BRE, launch the BizTalk Server installer.
    Figure 3. Select Components: To install the Microsoft BRE and corresponding Business Rules Framework, simply select the Business Rules Components option.

  1. Start the BizTalk Server 2006 or 2006 R2 installer and click ?Install Microsoft BizTalk Server on this computer? (see 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. Figure 4. Summary Screen: The Microsoft Business Rules Framework is installed automatically when you select the Business Rules Components item. These are the only components required to begin using Microsoft BRE immediately, however, you should also install the product documentation.
    Figure 5. Installation Complete: After the install completes, you still need to configure the Microsoft BRE components.

  4. You will see a Summary screen (see Figure 4) summarizing the fact that you are installing only documentation and core components necessary for the BRE. Click ?Install? to begin installation.
  5. Figure 6. Configuring BRE: Configuration is simple and requires only a host name and account credentials for the Rule Engine Update Service.
  6. After a few moments, you will be presented with an Installation Progress screen that takes a couple of minutes to complete. When it’s done, you’ll see a corresponding screen as shown in Figure 5. Make sure to check ?Launch BizTalk Configuration? and click Finish to begin configuring BRE.
  7. 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.
  8. Click Next and, in a few moments, configuration should complete and succeed (see Figure 8).

  9. Figure 7. Summary Screen: This summary screen lists the components that will be configured.
    Figure 8. Final Screen: After a few minutes, you should see this screen, letting you know that the BRE installed successfully.

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
Here, you’ll continue working with the same business rule used in the previous discussions. Without knowing anything about the business domain, by simply reading the rule in plain English, it is evident that you’re dealing with a customer and purchase domain.

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 percent discount to the purchase order.

Figure 9 shows a model of the Customer and PurchaseOrder entities. You can see the code for each entity in Listing 1 and Listing 2. Recall that the BRE can work with XML, a database or .NET objects; this case models the domain by using C# classes. The article code simply uses those same objects when working with the BRE.

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

The downloadable sample code for this article 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 let you emergently build the application layer.

After downloading the solution, make a copy of the file, unzip it, open the MSBRESample.sln file, and delete the contents of the PurchaseService.cs and PurchaseServiceTests.cs files in the Acme.RetailOperations project. Although there isn’t much code to write, I want to show you how powerful Test-Driven-Development coupled with the Microsoft Business Rules Engine can be?not only in decoupling the business rules from your application layer, but also in writing just enough code to get the job done. I have also provided all code listings, so you should also be able to follow along without firing up Visual Studio.

First, here’s a test method to exercise the application to ensure it correctly adheres to the 10 percent discount rule for customers with a preferred membership status. The following test method is called ExecuteCustomerCheckOutDiscountAmountShouldBeTenPercent. The name tells you two things: that it’s exercising the CustomerCheckOut method on the PurchaseService, and that the DiscountAmount property on the customer instance is 10 percent as shown in Listing 3 which contains the unit test code.

Of course, when you try to compile the Acme.RetailOperations.Tests project, you’ll get a bunch of compilation errors because the CustomerCheckOut method doesn’t exist yet.

Open the empty PurchaseService class and write enough code to at least get the unit test to compile. Listing 4 shows a very primitive CustomerCheckout method implementation. 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 will fail if you run it, because the unit test sets up the Customer and PurchaseOrder DiscountPercentage to 0 percent. Despite the PreferredMember property being set to true, there is no business rule or policy that acts on this fact (the body of the CustomerCheckout method is empty), so, as expected, the test fails (see Figure 10).

Figure 10. Failed Unit Test: The unit test fails because the Microsoft BRE policy has not yet been integrated into the application layer.
Figure 11. Business Rules Composer: Start the Business Rules Composer from the Microsoft BizTalk Server 2006 program group.

The goal now is to write enough code to get the test to pass, so 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’ll 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, notice that the new Policy is automatically versioned to 1.0. Right-click the version, select “Add New Rule,” and name the rule “Preferred Member Customer Discount.”

Figure 12. New Policy: Adding a new policy lets you group business roles according to domain-specific groups.
Figure 13. Fixed Policies: After creating a new policy, it is versioned and cannot be changed after deployment 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 this equality predicate to determine if the customer is a preferred member.

Figure 14. Predicates: The equality predicate is just one of several predicates for building conditional business rules within the Business Rules Composer.
Figure 15. Global Assembly Cache: You must add assemblies containing assertable facts to the GAC.

To use the predicate, you need to tell the BRE which fact slot will contain the data that determines whether the customer is a preferred member, so under Fact Explorer, click the .NET Class tab, right-click “.NET Assemblies” and then 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 (GAC), 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.

Figure 16. Facts and Fact Slots: Facts consist of fact slots, which in the case of .NET types include accessors for working with the fact.
Figure 17. Equality Predicates: An equality predicate requires two arguments. You provide the first argument by dragging and dropping the pertinent fact slot from the Customer fact.

Both Customer and PurchaseOrder classes are enumerated under the “.NET Assemblies” root. If you expand the Customer class, you will find accessors for all public properties, including the PreferredMember property (see Figure 16). Drag the PreferredMember get accessor to the Condition surface area, and drop it 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.

Figure 18. Conditions: A condition is simply an If/Then statement that always results in a Boolean true or false.
Figure 19. Completed Rule: A business rule is the combination of the condition and the action to take when the condition evaluates to true.

With the condition complete, all that’s 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 percent. 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.

Note that creating vocabulary definitions is useful for creating friendly names to apply to 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!). However, because this example uses .NET types modeled after the business domain, I have skipped creating vocabulary definitions altogether here.

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.

Testing Policies
Recall that a policy is the logical unit of deployment and can contain one or more rules. Also recall that policies are versioned and that deployed policies are immutable. Therefore, before you publish and deploy a policy, you need to test it.

Testing Policies 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. Therefore, even for testing purposes, you must 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.”

Creating a Fact Creator is straightforward. You simply need to implement the IFactCreator interface on a class to provide a surrogate Customer class to the BRE using a prescribed interface.

The CustomerFactCreator class (see Listing 5) shows the IFactCreator implementation. The CreateFacts method fulfills a contract to return an array of objects. The BRE uses these objects to conduct a pre-deployment test. In this case, I simply copied and pasted the Customer and PurchaseOrder initialization code from the unit test to the CreateFacts method, created a one-dimensional 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 that lets you select the CustomerFactCreator. Click “Add,” select the Acme.BusinessEntities.dll from the list of .NET assemblies, and then click “OK.” The Business Rules Composer queries the selected assembly for any Fact Creators and enumerates them. As shown in Figure 21, select the CustomerFactCreator and click “OK.”

Figure 20. Test Policy: The Business Rules Composer includes an integrated tool for testing condition behavior and agenda plan.
Figure 21. Fact Creator: You must supply a Fact Creator to the Business Rules Composer testing tool to assert the required facts for execution.

Now click “Test.” Immediately, the testing tool displays the agenda results in the test output pane as shown in Figure 22.

Understanding Agendas and Priority
Here’s a closer look at the Customer Discounts Policy test as shown in the agenda results in Figure 22.

Figure 22. Test Results: The testing tool displays agenda results immediately following the assertion of test facts into the BRE.

CustomerFactCreator asserted a Customer instance as a fact to the BRE. The BRE then looked for any rules containing conditions which map to fact slots present in the asserted fact (the Customer). Because the Customer indeed contains a field that indicates whether the sample customer is a preferred member, the BRE adds that rule to the agenda and executes it. The condition evaluated to true, because the PreferredMember fact slot on the Customer fact was set to true in your CustomerFactCreator. Because the Customer was asserted as a short-term fact, and there are no other rules in the policy, the BRE removes the Customer instance from memory and the 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. You can set a priority on each rule within the Business Rule Composer. Rules with a higher priority fire first.This has been a good way to test that the rule condition behaves as expected, and that the agenda is loading rules according to the expected priority, but you still don’t know if the action works as designed. Unfortunately, there’s no good way to do this within the Business Rules Composer. However, you’ll find a unit test in your Visual Studio solution that is up to 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. Note that after deployment, you can no longer modify the policy by editing existing rules, removing rules, or adding new ones. Because the policy has been deployed, you cannot change it; instead, you must create a new version of the policy to modify it.

Recall that although your ExecuteCustomerCheckOutDiscountAmountShouldBeTenPercent unit test compiled (see Listing 3) the last time you exercised it, it failed because the CustomerCheckOut method skeleton wasn’t yet implemented, and therefore, the DiscountPercentage is zero?just as it was before the test ran.

Figure 23. Deploying Policies: The You can deploy policies to the repository directly from the Business Rules Composer, or by using the BRE Deployment Utility (not shown).
Figure 24. Integrating the BRE: Programming with the Microsoft BRE is as simple as adding a reference to the Microsoft.BusinessRules.dll assembly.

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 you need to integrate the Microsoft BRE into your application. The Microsoft.RuleEngine.dll assembly resides in the C:Program FilesMicrosoft BizTalk Server 2006 folder as shown in Figure 24.

To focus on enforcing the business rule, I won’t show any other implementation details, but for completeness, you certainly might expect a real-world implementation of the CustomerCheckOut method to carry out additional chores, such as checking inventory, calculating shipping charges, and authorizing a credit card.

After adding the reference to the Microsoft.RulesEngine.dll, add the following using statement to the PurchaseService.cs file:

using Microsoft.RuleEngine;

Listing 4 shows the code for the PurchaseService class, which acts as your primitive application layer.

Figure 25. Successful Unit Test: After integrating the BRE policy into the application layer, unit tests are critical to ensure that corresponding actions behave as expected.

You need to split the Customer and PurchaseOrder 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, instantiate a Policy and provide the name of the policy in the constructor. Note that you can also provide a specific version of the policy, but?if omitted?the BRE will always use the newest policy version. Now, call Execute on the Policy instance, passing in the facts array.

When the BRE finishes executing the policy, it sets the DiscountPercentage property on the instance of the Customer class to 10 percent. The PurchaseService maintains a reference to that instance. If you now re-run the ExecuteCustomerCheckOutDiscountAmountShouldBeTenPercent unit test, it should pass with flying colors as shown in Figure 25.

While this is a very simplistic implementation of a purchasing application layer, you can probably already see that the loose coupling between the application layer and the business rules is powerful indeed. Not only do you have less code to write (you’ve harnessed the power of a fully featured rule-based engine with two lines of code), but the discount policy is free to evolve with the needs of the business.

For example, suppose a decision was made to increase or decrease the discount amount for preferred members, or even to eliminate the rule altogether? Implementing 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 introduces a new business rule that ensures that the combination of the preferred member discount and any current sales discounts do not cause the final price to fall below margin. This is important, because it ensures 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 that may initially sound complex, it is really very simple. This rule needs to be considered only 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 percent discount rule fires first. Only after the Discount Percentage fact slot gets updated would the margin protection rule be considered. When a 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. In other words, the BRE would complete two cycles. The second cycle would fire as a result of the Discount Percentage fact being changed, and thus cause a forward chaining of execution.

Play by the Rules
You’ve seen an overview of rule-based engine technology using Microsoft?s Business Rules Engine implementation, which is based on the Microsoft Business Rules Framework.

You saw how development can use an emergent approach by building the customer check-out functionality in the sample application 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 the 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!

One final word of advice: It is very important to understand that despite the compelling productivity improvements that Microsoft BRE can 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; technology projects for technology?s sake rarely provide convincing evidence of value 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 such as Microsoft BRE are merely one vehicle for doing so. Don?t confuse the two.

The CHAOS report finds that 7 percent of features in an application are always used, and 13 percent of features are used often, and. My advice to you is to work with the business members of your team to identify that sweet spot, and then start simply, with a business process or business rule or two. By taking a middle-out approach, you’ll quickly and easily find the processes to which applying business rule flexibility will add significant business value. Think big, start small, prove your business case, and the rest will follow.

See also  Comparing different methods of testing your Infrastructure-as-Code

About Our Editorial Process

At DevX, we’re dedicated to tech entrepreneurship. Our team closely follows industry shifts, new products, AI breakthroughs, technology trends, and funding announcements. Articles undergo thorough editing to ensure accuracy and clarity, reflecting DevX’s style and supporting entrepreneurs in the tech sphere.

See our full editorial policy.

About Our Journalist