Last month we looked at what business rules are and how
they fit in the overall BizTalk paradigm. This time we will actually put our
hands in the code and see how the rules can be used within the BizTalk
Orchestrations as well as through the .NET apps. A .NET application using the
business rules need to not necessarily be a Windows or a Web application. Infact,
it can be just anything that is possible with .NET. It can be a win forms
application or a web application. It can even be a web service or just a plain
component that will be used with some other solution. Business Rules Framework
exposes its .NET API in a fairly non-restrictive way. Obviously, the application
needs to have rights to consume the rules component. Let's create a simple
rule. The rule takes a Purchase Order document and checks the amount. If the
amount is more than 25000, it just marks another field 'ApprovalRequired' as
true. The .NET API exposed by the Business Rules Engine offers a great deal of
flexibility to generate and publish the rules dynamically through the
application and then using them. However, we will resort to using the Rules
Composer for this discussion.
|
Understanding the Business Rules composer
The Business Rules Composer offers an intuitive user interface to play with
the rules. Rules are based on facts. Several such rules form a 'ruleset' or
a policy. On opening the Business Rules Composer, it connects to the Rule
Database and loads the deployed policies in the Policy Explorer pane. Its
associated vocabularies are loaded in the Facts Explorer pane. To add a new
policy, simply right click on the policies root node and select 'Add a new
policy'. A blank policy is added with its default version 1.0.
Associated facts can be created before creating the rule from the Facts
Explorer. Facts can be picked up from XML Documents, .NET components, and
database tables.
The Vocabulary definition wizard allows defining these
facts as vocabularies. The Wizard initially asks to choose from the various
options available for facts. In our example, we will be using an input XML
document. Fields from this document will act as facts. Hence, we will be using
the vocabulary definition wizard to enhance our vocabulary from these facts
available in our input XML document. Once done with creating the vocabularies,
we can go ahead and add a new rule. To add a new rule, right click on the latest
version and select 'Add a new Rule'. A blank rule is created. Associated
facts can be dragged onto the rule to form a complete rule. Logical conditions
can again be added by right clicking. Predicates like 'equal to', 'greater
than' etc, can be used from the available list of predicates. Complex rules
can also define their own custom predicates from the Facts Explorer pane.
The functionality BizTalk Business rules engine can be harnessed by either the .NET API or even the BizTalk orchestrations |
Consuming rules using BizTalk orchestration
Although much of the orchestration processing works as a procedural code,
there are instances in the solution wherein significant chunk of the processing
might involve dealing with the business rules. The orchestration engine thus
exposes features to interact with the rules from within the orchestration with
the help of the 'Call Rules'. The Call Rules shape takes in the data
from the
orchestration in form of the XML messages or the
orchestration variables and uses this data to evaluate its policies. The
policies may also play around with the data received from orchestration. For our
rules example, the policies will update the 'ApprovalFlag' field based on
the result of the rule. Configuring the Call Rules shape within the
orchestration is quite an easy task to achieve. It expects just two things
-first the policy that is to be evaluated (of course this policy has to be
deployed in the Rules database before it can be used). This can be selected from
the drop down that automatically populates the list of policies that are
published to the rules store (database). The second input expected in the call
rules shape are the actual inputs required for the evaluation. This can be
either the XML message or the orchestration variable. These inputs act as facts
for the rules evaluation. Based on how the selected policy is deployed, the Call
Rules shape provides a drop down of the input type for each corresponding row of
the input parameter. The rules so evaluated are capable of modifying the message
to include new values based on the result of evaluation. Effectively, this
leaves the orchestration data vulnerable to changes outside the scope of the
orchestration. Hence, to avoid inconsistency, the compiler mandates that the
call Rules shape should be embedded in an atomic scope. Putting it in an atomic
scope ensures that the orchestration writes itself along with its current state
and data to the SQL Server database before allowing the rules engine to let
loose on its data. In case of any problem with processing from the Rules engine,
the orchestration can always get details about its state from the database.
The Business Rules Composer allows a unified, flexible and easy to use view for composing the Business Rules |
Accessing rules from .NET components
The Rules engine requires a host where it can execute. When calling them
from the BizTalk orchestrations, the orchestrations act as a host for the rules.
Alternatively, rules can be hosted even within a .NET-based application by
making use of the .NET-based APIs exposed by the engine. These APIs help the
non-BizTalk solutions harness the benefits of the Rules framework. These can be
used by any .NET application irrespective of their types. So it can be a
Windows-based or a web-based application or a Web service even. The only obvious
criterion is the access to execute the Rules Engine API.
The API provides the 'Policy' class that can be used to
access the policy. This is a very basic and commonly used class required to
execute a policy. The policy can be selected based on the Policy name and its
version. The application can equip it with array of objects that can act as
facts to the rules contained within the policy. After assigning the required
'facts' as objects, the application can simply execute the 'Execute()'
method to execute the Rules.
The APIs provide several other set of classes along with
the Policy class to interact further. It allows you to define the rules, facts
and policies on the fly and also to deploy or publish them in the Rules Engine
Database. The code snippet here demonstrates calling of a simple policy from the
.NET code. You will need to include the Microsoft.Rule Engine and the Microsoft.
Biztalk.Rule EngineExtensions assemblies found in the BizTalk Home folder for
this code to work.
//Using Microsoft.RuleEnginre and //Microsoft.Biztalk.Rule EngineExtensions//Reference these assemblies from BizTalk home dirXmlDocument xTestInstance = new XmlDocument();xTestInstance.Load ("template.xml"); //Assign the values from our test screenxTestInstance.SelectSingleNode ("//PONumber").InnerText = txtPONumber.Text;xTestInstance.SelectSingleNode("//POAmount").InnerText = txtPOAmount.Text; xTestInstance.SelectSingleNode("//CreatedBy").InnerText = txtCreatedBy.Text;TypedXmlDocument typedInstanceDoc = new TypedXmlDocument("POSchema",xTestInstance);try{ object <>arrFacts = new object<1>; Policy pol = new Policy("PurchaseApprovalPolicy",1,2); arrFacts<0> = typedInstanceDoc; pol.Execute(arrFacts); pol.Dispose(); }catch(Exception ex){ MessageBox.Show("Exception occured while trying to execute the policy - " + ex.Message);} |
The Fact Retriever interface
The Fact Retriever is similar to the concept of 'Long term facts'. Long
term facts are those that can be used over a period of time, the term is
synonymous to caching of the facts. Normally facts would be gathered at the time
of execution of the rule and are available during execution. Using Long term
facts, these facts are 'cached' using a .NET assembly and can be reused for
multiple executions. The storing of these facts can be decided by the .NET
assembly that will be referenced when facts are created in the composer. The
APIs expose an interface named 'IFactRetriever' that helps in building such
components. The interface mandates implementation of the UpdateFacts() method,
which returns an instance of the System.Object which is used by the Rules Engine
for using the updated facts.
The rules engine helps separate the business rules from the
execution logic. This becomes important looking at the fact that the rules are
the most volatile part of the entire solution. Rules Engine allows changing the
rules dynamically without affecting the application logic that is depending on
them. They expose a rich set of .NET based APIs that can be used to use the
rules either from the BizTalk Orchestration or from any other .NET applications.
Sanket Bakshi