Documentos de Académico
Documentos de Profesional
Documentos de Cultura
CODE Magazine - Article: Programming with the Microsoft Business Rules Framework
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
1/21
www.code-magazine.com/articleprint.aspx?quickid=0811071&printmode=true
9/2/13
CODE Magazine - Article: Programming with the Microsoft Business Rules Framework
Scott W. Ambler presents some compelling facts about the inevitability of change in our software applications: http://www.agilemodeling.com/essays/examiningBRUF.htm
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.
MSDN Documentation
Complete documentation for the Microsoft BRE is available on the MSDN Network: http://msdn.microsoft.com/enus/library/aa577691.aspx
Solution Download
You can download the code for this article at http://rickgaribay.net/
www.code-magazine.com/articleprint.aspx?quickid=0811071&printmode=true
2/21
9/2/13
CODE Magazine - Article: Programming with the Microsoft Business Rules Framework
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.
"
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 inferencebased 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 Microsofts 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 Isnt 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 rulebased 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
www.code-magazine.com/articleprint.aspx?quickid=0811071&printmode=true
3/21
9/2/13
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.
CODE Magazine - Article: Programming with the Microsoft Business Rules Framework
Figure 1: The Microsoft Business Rules Framework consists of designtime 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 inmemory 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.
www.code-magazine.com/articleprint.aspx?quickid=0811071&printmode=true
4/21
9/2/13
CODE Magazine - Article: Programming with the Microsoft Business Rules Framework
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 Engines 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. Ill 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.
www.code-magazine.com/articleprint.aspx?quickid=0811071&printmode=true
Rule
5/21
9/2/13
Rule
CODE Magazine - Article: Programming with the Microsoft Business Rules Framework
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 nondevelopers, 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.
of CIO budgets are spent " Up to 70% on maintenance. " In fact, as youll learn below, you can install the BRE completely independently of other BizTalk components, making installation a breeze:
www.code-magazine.com/articleprint.aspx?quickid=0811071&printmode=true
6/21
9/2/13
CODE Magazine - Article: Programming with the Microsoft Business Rules Framework
Figure 2: To install Microsoft BRE, simply launch the BizTalk Server installer. Figure 3: Installation of the Microsoft BRE and corresponding Business Rules Framework simply consists of selecting the Business Rules Components option.
www.code-magazine.com/articleprint.aspx?quickid=0811071&printmode=true
7/21
9/2/13
CODE Magazine - Article: Programming with the Microsoft Business Rules Framework
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.
Figure 6: Configuration is very simple and only requires a host name and account credentials for the Rule Engine Update Service.
www.code-magazine.com/articleprint.aspx?quickid=0811071&printmode=true
8/21
9/2/13
CODE Magazine - Article: Programming with the Microsoft Business Rules Framework
Figure 8: The Microsoft BRE is installed successfully in a matter of minutes. A gentle reminder: Please remember that although Business Rules Framework and BRE components are fully standalone configuration, any machine running BRE, BizTalk Server components must be fully licensed for 2006 or better. the Microsoft functional in a or any other BizTalk Server
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 Ive 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.
www.code-magazine.com/articleprint.aspx?quickid=0811071&printmode=true
9/21
9/2/13
CODE Magazine - Article: Programming with the Microsoft Business Rules Framework
Figure 9: The Customer and Purchase Order business entities are used to model the business domain. The sample code that Ive prepared for this article (please refer to sidebar Solution Download for download instructions) contains three projects:
5. I have also provided all code listings, so you should also be able
to follow along without firing up Visual Studio.
Figure 10: The unit test fails because the Microsoft BRE policy has not yet been integrated into the application layer.
www.code-magazine.com/articleprint.aspx?quickid=0811071&printmode=true
10/21
9/2/13
CODE Magazine - Article: Programming with the Microsoft Business Rules Framework
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 youll 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.
Figure 11: The Business Rules Composer is started from the Microsoft BizTalk Server 2006 program group.
Figure 12: Adding a new policy allows you to group business roles according to domain-specific groups.
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.
www.code-magazine.com/articleprint.aspx?quickid=0811071&printmode=true
11/21
9/2/13
CODE Magazine - Article: Programming with the Microsoft Business Rules Framework
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.
www.code-magazine.com/articleprint.aspx?quickid=0811071&printmode=true
12/21
9/2/13
CODE Magazine - Article: Programming with the Microsoft Business Rules Framework
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.
Figure 16: Facts consist of fact slots, which in the case of .NET types include assessors for working with the fact.
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.
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.
www.code-magazine.com/articleprint.aspx?quickid=0811071&printmode=true
13/21
9/2/13
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.
CODE Magazine - Article: Programming with the Microsoft Business Rules Framework
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 interrole 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. are two or more rules that " If there 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, policy is the logical unit of deployment. Also recall versioned and once a policy has been deployed, Therefore, before you publish and deploy the policy, it. and as such the that policies are it is immutable. you need to test
Testing a Policy by Implementing the IFactCreator Interface As Ive 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
www.code-magazine.com/articleprint.aspx?quickid=0811071&printmode=true
14/21
9/2/13
CODE Magazine - Article: Programming with the Microsoft Business Rules Framework
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.
Figure 20: The Business Rules Composer includes an integrated tool for testing condition behavior and agenda plan. 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. 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
www.code-magazine.com/articleprint.aspx?quickid=0811071&printmode=true
15/21
9/2/13
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.
CODE Magazine - Article: Programming with the Microsoft Business Rules Framework
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 dont 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. 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 messagebased, 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. 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: u s i n gM i c r o s o f t . R u l e E n g i n e ; 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.
www.code-magazine.com/articleprint.aspx?quickid=0811071&printmode=true
When
the
BRE
is
done
executing the
policy,
it
will set
the
16/21
9/2/13
CODE Magazine - Article: Programming with the Microsoft Business Rules Framework
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. 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 (youve 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. Rule Engine class takes a policy " The(rule set) as an argument and determines which rules are applicable given the facts, translates the rules from BRL to inmemory 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 t he final price to fall below margin. This is important to ensure that the preferred membership program doesnt 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 Microsofts 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
www.code-magazine.com/articleprint.aspx?quickid=0811071&printmode=true
17/21
9/2/13
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 t his 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! can install the BRE completely " You independently of other BizTalk components, making installation a breeze!
CODE Magazine - Article: Programming with the Microsoft Business Rules Framework
"
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 technologys 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. Dont 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
Listing 1: The Customer Domain Entity. u s i n gS y s t e m ; u s i n gS y s t e m . T e x t ; n a m e s p a c eA c m e . B u s i n e s s E n t i t i e s { / / /< s u m m a r y > / / /E n c a p s u l a t e se l e m e n t su s e dt od e s c r i b eac u s t o m e r . / / /< / s u m m a r y > p u b l i cc l a s sC u s t o m e r { p r i v a t es t r i n gm _ F i r s t N a m e ; p r i v a t es t r i n gm _ L a s t N a m e ; p r i v a t eb o o lm _ P r e f e r r e d M e m b e r ; p r i v a t eP u r c h a s e O r d e rm _ O r d e r ;
www.code-magazine.com/articleprint.aspx?quickid=0811071&printmode=true
18/21
9/2/13
}
s e t{m _ P r e f e r r e d M e m b e r=v a l u e ;}
CODE Magazine - Article: Programming with the Microsoft Business Rules Framework
} }
Listing 2: The Purchase Order Domain Entity. u s i n gS y s t e m ; u s i n gS y s t e m . T e x t ; n a m e s p a c eA c m e . B u s i n e s s E n t i t i e s { / / /< s u m m a r y > / / /E n c a p s u l a t e se l e m e n t su s e dt od e s c r i b eap u r c h a s eo r d e r . / / /< / s u m m a r y > p u b l i cc l a s sP u r c h a s e O r d e r { p r i v a t es t r i n gm _ P u r c h a s e O r d e r I d ; p r i v a t ei n tm _ T o t a l I t e m s ; p r i v a t ed e c i m a lm _ T o t a l P u r c h a s e A m o u n t ; p r i v a t ef l o a tm _ D i s c o u n t P e r c e n t a g e ; p r i v a t ed e c i m a lm _ S h i p p i n g C o s t ; p r i v a t ed e c i m a lm _ T o t a l I n c l u d i n g S h i p p i n g ;
} }
www.code-magazine.com/articleprint.aspx?quickid=0811071&printmode=true
19/21
9/2/13
u s i n gA c m e . R e t a i l O p e r a t i o n s ;
CODE Magazine - Article: Programming with the Microsoft Business Rules Framework
n a m e s p a c eA c m e . R e t a i l O p e r a t i o n s . T e s t s { [ T e s t C l a s s ] p u b l i cc l a s sP u r h a s e S e r v i c e { p u b l i cP u r h a s e S e r v i c e ( ) { / / / /T O D O :A d dc o n s t r u c t o rl o g i ch e r e / / } p r i v a t eT e s t C o n t e x tt e s t C o n t e x t I n s t a n c e ; p u b l i cT e s t C o n t e x tT e s t C o n t e x t { g e t { r e t u r nt e s t C o n t e x t I n s t a n c e ; } s e t { t e s t C o n t e x t I n s t a n c e=v a l u e ; } }
[ T e s t M e t h o d ] p u b l i cv o i dE x e c C u s t o m e r C h e c k O u t D i s c A m t S h o u l d B e T e n P e r c e n t ( ) { C u s t o m e rc u s t o m e r=n e wC u s t o m e r ( ) ; c u s t o m e r . F i r s t N a m e=" R o b e r t " ; c u s t o m e r . L a s t N a m e=" D e n i r o " ; c u s t o m e r . P r e f e r r e d M e m b e r=t r u e ; P u r c h a s e O r d e ro r d e r=n e wP u r c h a s e O r d e r ( ) ; o r d e r . D i s c o u n t P e r c e n t a g e=0 f ; c u s t o m e r . O r d e r=o r d e r ; P u r c h a s e S e r v i c es e r v i c e=n e wP u r c h a s e S e r v i c e ( ) ; s e r v i c e . C u s t o m e r C h e c k o u t ( c u s t o m e r ) ; A s s e r t . I s T r u e ( c u s t o m e r . O r d e r . D i s c o u n t P e r c e n t a g e= =. 1 0 f ," E x p e c t e d. 1 0b u tw a s{ 0 } " , c u s t o m e r . O r d e r . D i s c o u n t P e r c e n t a g e ) ; } } }
Listing 4: The PurchaseService Application Layer. u s i n gS y s t e m ; u s i n gS y s t e m . T e x t ; u s i n gA c m e . B u s i n e s s E n t i t i e s ; u s i n gM i c r o s o f t . R u l e E n g i n e ; n a m e s p a c eA c m e . R e t a i l O p e r a t i o n s { / / /< s u m m a r y > / / /P r o v i d e sp u r c h a s eo r d e r i n gf u n c t i o n a l i t ya n di n t e g r a t e sw i t hB R E . / / /< / s u m m a r y > p u b l i cc l a s sP u r c h a s e S e r v i c e { p u b l i cv o i dC u s t o m e r C h e c k o u t ( C u s t o m e rc u s t o m e r ) { o b j e c t [ ]f a c t s=n e wo b j e c t [ 2 ] ; P u r c h a s e O r d e ro r d e r=c u s t o m e r . O r d e r ; / /s o m el o g i c / /D e t e r m i n ea n yd i s c o u n t s P o l i c yp o l i c y=n e wP o l i c y ( " C u s t o m e rD i s c o u n t sP o l i c y " ) ; p o l i c y . E x e c u t e ( f a c t s ) ; c u s t o m e r . O r d e r=o r d e r ; / /s o m ea d d i t i o n a ll o g i c } } }
www.code-magazine.com/articleprint.aspx?quickid=0811071&printmode=true
20/21
9/2/13
u s i n gS y s t e m ; u s i n gS y s t e m . T e x t ; u s i n gM i c r o s o f t . R u l e E n g i n e ;
CODE Magazine - Article: Programming with the Microsoft Business Rules Framework
n a m e s p a c eA c m e . B u s i n e s s E n t i t i e s { / / /< s u m m a r y > / / /I m p l e m e n t st h eI F a c t C r e a t o ri n t e r f a c ef o rp r o v i d i n g. N E Tt y p e st ot h eB R Ef o rt e s t i n gp u r p o s e s . / / /< / s u m m a r y > p u b l i cc l a s sC u s t o m e r F a c t C r e a t o r:I F a c t C r e a t o r { # r e g i o nI F a c t C r e a t o rM e m b e r s p u b l i co b j e c t [ ]C r e a t e F a c t s ( R u l e S e t I n f or u l e S e t I n f o ) { o b j e c t [ ]f a c t s=n e wo b j e c t [ 1 ] ; C u s t o m e rc u s t o m e r=n e wC u s t o m e r ( ) ; c u s t o m e r . F i r s t N a m e=" R o b e r t " ; c u s t o m e r . L a s t N a m e=" D e n i r o " ; c u s t o m e r . P r e f e r r e d M e m b e r=t r u e ; P u r c h a s e O r d e ro r d e r=n e wP u r c h a s e O r d e r ( ) ; o r d e r . D i s c o u n t P e r c e n t a g e=0 f ; c u s t o m e r . O r d e r=o r d e r ; f a c t s [ 0 ]=c u s t o m e r ; r e t u r nf a c t s ; } p u b l i cT y p e [ ]G e t F a c t T y p e s ( R u l e S e t I n f or u l e S e t I n f o ) { t h r o wn e wN o t I m p l e m e n t e d E x c e p t i o n ( ) ; } # e n d r e g i o n } }
www.code-magazine.com/articleprint.aspx?quickid=0811071&printmode=true
21/21