Introduction
In BRE, facts are user data which are used in policy for conditional rule. Facts are categorized into long term and short term facts. Short term facts often change with requirement but long term facts do not change much. In this tip, I will show you how by using long term facts to increase the performance of your orchestration.
While calling a policy within an orchestration which uses database facts, each time we need to create a connection string in an expression shape. Then we call the policy by passing connectionstring
and required parameters. So, for every instance of orchestration, a new SQL connection is created and will effect the performance of your solution. Also, every time we have to write the same SQL connection code (redundant) for each orchestration which is calling this policy. This tip will help you to understand how to use long term facts to mitigate this type of issue and also provide a sample code which helps to restrict multiple instances of SQL connection (since it is using singleton pattern) and also, only one connection is shared between all the orchestration instances.
Background
Check this link Difference between long term and short term facts if you don't know the difference between long term and short term facts.
Problem this Solution Solves and How it is Useful
The problem of creating an unnecessary connection string for each orchestration instance can be solved using this technique. Also, suppose if the connection string is changed in the future, then you don't have to go to each orchestration to make changes. By changing it in one place it will be effected for the all the instances of orchestration. Thus, it helps while maintaining the solution for the future.
Using the Code
For this tip, let us create a class library 'FactsRetriever
'. Now, define a class 'AssertDBConnectionn
' which inherits IFactRetriver
interface. For a class to act as a long term fact for BRE, IFactRetriever
needs to be inherited. Next, we have to implement and define our connection string in UpdateFacts
method of IFactRetriever
interface class.
using System.Data.SqlClient;
using Microsoft.RuleEngine;
namespace FactsRetriver
{
public class AssertDBConnectionn: IFactRetriever
{
#region IFactRetriever Members
public object UpdateFacts(RuleSetInfo ruleSetInfo, RuleEngine engine, object factsHandleIn)
{
object factsHandleOut;
if (factsHandleIn == null)
{
SqlConnection SQLConn = new SqlConnection
("Data Source=.;Initial Catalog=StudentInfo;Integrated Security=SSPI;");
DataConnection RulesConn = new DataConnection
("StudentInfo", "StudentDetails", SQLConn);
factsHandleOut = RulesConn;
engine.Assert(factsHandleOut);
}
else
factsHandleOut = factsHandleIn;
return factsHandleOut;
}
#endregion
}
}
After creating the project, build it and gac it using gacutil
command in Visual Studio command prompt. Then select the policy which you have created and specify the location of DLL under properties section in Facts Retriever property as shown in the diagram below:
Code Description and How it Works
In this code a SQL Connection string gets created which is pointing to your server->database->table you are using as your facts. Next, the rule engine connection is created which expects database name, database table and a SQL connection string as a parameter. After creating a rule engine connection string it is assigned to the factsHandleOut
object and the engine asserted the factsHandleOut
into memory. Asserting the object means it is putting the object into memory so that the rule engine can directly reference it at runtime while executing the policy. For each call policy from orchestration, it first checks whether the object has already been asserted into memory since it is using singleton pattern.
Conclusion
By using this technique, I save a lot of time by not defining the connectionstring
each time I need to call the policy. Also, it increases the performance of my solution. So, before creating facts, first identify whether it's a long term fact or short term fact and then act accordingly.