Click here to Skip to main content
15,892,072 members
Articles / Web Development / HTML

Basic Help on NxBRE (Rule Engine)

Rate me:
Please Sign up or sign in to vote.
5.00/5 (7 votes)
16 Dec 2014CPOL1 min read 68.8K   2.3K   19   26
Here is a help on NxBRE (Rule Engine) for basic business rules

Introduction

In this article, we are going to see how we can apply dynamic business rules on an application without recompiling the code.

Background

My company required to build an ETL and my responsibility was to take care of the "T" Part.

You can found a brief about the DLL NxBRE here: http://sourceforge.net/projects/nxbre/. As I said I am not an expert of Rule engines, but this project might help you. 

It's nice to implement BRE in your application and your intelligence to code and writing business rules will speed up your application otherwise it may hamper performance.

Using the code 

You need VS 2010, this project will show you a small demo of Employee Tax and DA calculation depending on their Basic. Here is the XBRE file which contains the Rule:

XML
<?xml version="1.0" encoding="UTF-8"?>
<xBusinessRules xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
           xsi:noNamespaceSchemaLocation="xBusinessRules.xsd">
  <Decimal id ="Tax" value ="10"/>
  <Decimal id ="DAp" value ="10"/>
 
  <Decimal id="5000" value="5000"/>
  <Decimal id="10000" value="10000"/>
  <Decimal id="15000" value="15000"/>
  <Decimal id="20000" value="20000"/>
  <Decimal id="30000" value="30000"/>
  <Decimal id="100000" value="100000"/>
  
  <!-- Calculation Of Tax -->
  
  <ObjectLookup id ="EmpObj" objectId ="EmpTexCal" member ="BasicSalary"/>
  <Logic>
    <If>
      <And>
        <Between leftId ="5000" rightId ="10000" valueId ="EmpObj">
        </Between>
      </And>
      <Do>
        <Modify id ="Tax" type="Decimal" value ="11.5"/>
      </Do>
    </If>
    <ElseIf>
      <And>
        <Between leftId ="10000" rightId ="15000" 
                  valueId ="EmpObj" excludeLeft ="true">
        </Between>
      </And>
      <Do>
        <Modify id ="Tax" type="Decimal" value ="13.5"/>
      </Do>
    </ElseIf>
    <ElseIf>
      <And>
        <Between leftId ="15000" rightId ="20000" 
                    valueId ="EmpObj" excludeLeft ="true">
        </Between>
      </And>
      <Do>
        <Modify id ="Tax" type="Decimal" value ="14.5"/>
      </Do>
    </ElseIf>
    <ElseIf>
      <And>
        <Between leftId ="20000" rightId ="30000" 
                      valueId ="EmpObj" excludeLeft ="true">
        </Between>
      </And>
      <Do>
        <Modify id ="Tax" type="Decimal" value ="15.5"/>
      </Do>
    </ElseIf>
    <ElseIf>
      <And>
        <Between leftId ="30000" rightId ="100000" 
                    valueId ="EmpObj" excludeLeft ="true">
        </Between>
      </And>
      <Do>
        <Modify id ="Tax" type="Decimal" value ="17"/>
      </Do>
    </ElseIf>
  </Logic>
 
  <!-- <ObjectLookup id ="EmpObjOut" 
               objectId ="EmpTexCal" member ="TaxPercentage">
    <Argument valueId="Tax"/>
 </ObjectLookup> -->
  <!-- Calculation Of DA -->
  <Logic>
    <If>
      <And>
        <Between leftId ="5000" rightId ="10000" valueId ="EmpObj">
        </Between>
      </And>
      <Do>
        <Modify id ="DAp" type="Decimal" value ="25"/>
      </Do>
    </If>
    <ElseIf>
      <And>
        <Between leftId ="10000" rightId ="15000" valueId ="EmpObj" excludeLeft ="true">
        </Between>
      </And>
      <Do>
        <Modify id ="DAp" type="Decimal" value ="30"/>
      </Do>
    </ElseIf>
    <ElseIf>
      <And>
        <Between leftId ="15000" rightId ="20000" valueId ="EmpObj" excludeLeft ="true">
        </Between>
      </And>
      <Do>
        <Modify id ="DAp" type="Decimal" value ="40"/>
      </Do>
    </ElseIf>
    <ElseIf>
      <And>
        <Between leftId ="20000" rightId ="30000" valueId ="EmpObj" excludeLeft ="true">
        </Between>
      </And>
      <Do>
        <Modify id ="DAp" type="Decimal" value ="50"/>
      </Do>
    </ElseIf>
    <ElseIf>
      <And>
        <Between leftId ="30000" rightId ="100000" valueId ="EmpObj" excludeLeft ="true">
        </Between>
      </And>
      <Do>
        <Modify id ="DAp" type="Decimal" value ="60"/>
      </Do>
    </ElseIf>
  </Logic>
  <!-- Example Of Evaluation -->
  <ObjectLookup id="ExpDAp"	type="NxBRE.Imp.Util.Evaluator,NxBRE.Imp" member="CreateExpression">
    <Argument value="(" />
    <Argument valueId="EmpObj" />
    <Argument value="/" />
    <Argument value="100" />
    <Argument value=")" />
    <Argument value="*" />
    <Argument valueId="DAp" />
  </ObjectLookup>
  <ObjectLookup id="EvalDAp"	type="NxBRE.Util.Compilation" member="Evaluate">
    <Argument valueId="ExpDAp" />
  </ObjectLookup>
  <ObjectLookup id="CastDAp"	type="NxBRE.Imp.Util.Casting,NxBRE.Imp" member="CastData">
    <Argument valueId="EvalDAp" />
    <Argument value="System.Decimal" />
  </ObjectLookup>
  <ObjectLookup id ="EmpObjOut" objectId ="EmpTexCal" member ="DA">
    <Argument valueId="CastDAp"/>
  </ObjectLookup>
</xBusinessRules> 

Here is how to read the XBRE file, I will explain the XBRE file later:

C#
public ReadRule(string RuleFilePath)
{
    _FilePath = RuleFilePath;
    StringBuilder sb=new StringBuilder(255);

    if (GetShortPathName(_FilePath, sb, sb.Capacity) != 0)
        _factory = new BREFactoryConsole(_engineTraceLevel, _ruleBaseTraceLevel).NewBRE(new XBusinessRulesFileDriver(sb.ToString()));
}

You can change trace level to get trace result. I have two separate concerns: one is reading rule from a file and setting values for depending calculations.

Set value of depending variables. Set value of a particular object. 

C#
public void SetObjectRefrance(ReadRule objRule, string ObjectId, object Obj)
{
    if (objRule.IsValidXML)
    {
        if (objRule.IsProcessed)
            objRule.Reset();
        objRule.Factory.RuleContext.SetObject(ObjectId, Obj);
    }
}

We can set any delegate of ExecuteRuleDelegate type through which we can call back our base code while performing rules.

C#
public void SetDelegateRefrance(ReadRule objRule, string ObjectId, ExecuteRuleDelegate Delegate)
{
    if (objRule.IsValidXML)
    {
        if (objRule.IsProcessed)
            objRule.Reset();
        objRule.Factory.RuleContext.SetFactory(ObjectId, new BRERuleFactory(Delegate));
    }
}

In this rule engine we can split our rule concern and perform partial rule or we can perform the rule but fetch only partial result values.

* We have to set depending values or the Delegate.

C#
public object GetRuleResult(ReadRule objRule, string ObjectId)
{
    try
    {
        if (!objRule.IsProcessed)
            objRule.ProcessRules();
        return objRule.Factory.RuleContext.GetResult(ObjectId).Result;
    }
    catch (Exception)
    {
    }

    return FlagResualt.NoProcessed;
}

Now I have created a combine function which will take care of all of the above functions:

C#
public void EvaluateRule(ReadRule objRule, RuleRefrance[] RulesReferances, 
              RuleDelegate[] RulesDelegates, RuleResualt[] RuleReply)
{
    if (RulesReferances != null)
        AddObjects(objRule, 0, RulesReferances);
    if (RulesDelegates != null)
        AddDelegates(objRule, 0, RulesDelegates);
    // Process Rules
    if (!objRule.IsProcessed)
        objRule.ProcessRules();

    //if (RuleReply != null)
    GetObjectResult(objRule, 0, RuleReply);

}

GetObjectResult just sets values at our ORM or any other class using Reflection.

Now how to call all of this and get the rule output, it's very simple:

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect ICRA Online Ltd.
India India
He has a experience of 10+ years in .Net Technology, he like to learn and share thinks about coding and development process.

Quora | LinkedIn | Twitter

Comments and Discussions

 
Questionanother question Pin
Member 130262215-Apr-17 15:48
Member 130262215-Apr-17 15:48 
AnswerRe: another question Pin
Suvabrata Roy6-Apr-17 21:06
professionalSuvabrata Roy6-Apr-17 21:06 
QuestionI want to know how to write the xbre file Pin
Member 1302622110-Mar-17 15:57
Member 1302622110-Mar-17 15:57 
AnswerRe: I want to know how to write the xbre file Pin
Suvabrata Roy12-Mar-17 20:23
professionalSuvabrata Roy12-Mar-17 20:23 
GeneralRe: I want to know how to write the xbre file Pin
Member 1302622122-Mar-17 21:56
Member 1302622122-Mar-17 21:56 
QuestionUserIntreface Pin
schalla12323-Jan-17 10:15
schalla12323-Jan-17 10:15 
AnswerRe: UserIntreface Pin
Suvabrata Roy23-Jan-17 20:34
professionalSuvabrata Roy23-Jan-17 20:34 
QuestionDoesn't seem to work with .NET 4.5.1 Pin
Sunam3924-Nov-14 10:44
Sunam3924-Nov-14 10:44 
AnswerRe: Doesn't seem to work with .NET 4.5.1 Pin
Suvabrata Roy29-Nov-14 8:58
professionalSuvabrata Roy29-Nov-14 8:58 
GeneralRe: Doesn't seem to work with .NET 4.5.1 Pin
Sunam394-Dec-14 2:37
Sunam394-Dec-14 2:37 
GeneralRe: Doesn't seem to work with .NET 4.5.1 Pin
Suvabrata Roy4-Dec-14 2:39
professionalSuvabrata Roy4-Dec-14 2:39 
GeneralRe: Doesn't seem to work with .NET 4.5.1 Pin
Suvabrata Roy18-Dec-14 17:32
professionalSuvabrata Roy18-Dec-14 17:32 
QuestionStyle of Name on profile Page Pin
Akhil Mittal8-Jun-14 22:55
professionalAkhil Mittal8-Jun-14 22:55 
AnswerRe: Style of Name on profile Page Pin
Suvabrata Roy8-Jun-14 23:27
professionalSuvabrata Roy8-Jun-14 23:27 
QuestionThank you! Pin
David Dossot1-Oct-12 6:34
David Dossot1-Oct-12 6:34 
AnswerRe: Thank you! Pin
Suvabrata Roy3-Oct-12 4:27
professionalSuvabrata Roy3-Oct-12 4:27 
Questionanother question Pin
CodingABC17-Sep-12 9:32
CodingABC17-Sep-12 9:32 
AnswerRe: another question Pin
Suvabrata Roy18-Sep-12 5:50
professionalSuvabrata Roy18-Sep-12 5:50 
GeneralRe: another question Pin
CodingABC25-Sep-12 9:00
CodingABC25-Sep-12 9:00 
QuestionDo you know how to access a class member from the xbre file? Pin
CodingABC6-Sep-12 6:54
CodingABC6-Sep-12 6:54 
AnswerRe: Do you know how to access a class member from the xbre file? Pin
Suvabrata Roy10-Sep-12 1:51
professionalSuvabrata Roy10-Sep-12 1:51 
GeneralRe: Do you know how to access a class member from the xbre file? Pin
CodingABC10-Sep-12 3:13
CodingABC10-Sep-12 3:13 
Thanks for your time..

I have the following classes:

public sealed class Security
{
public string symbol { get; set; }
public double currentPrice { get; set; }

public Security(string symbol, double currentprice)
{
this.currentPrice = currentprice;
this.symbol = symbol;
}

public Security()
{
}

}


public sealed class Position
{
public Security security { get; set; }
public double purchasedPrice { get; set; }
public int quantity { get; set; }

public Position()
{
}
public Position(Security security, double purchasedPrice, int quantity)
{
this.security = security;
this.purchasedPrice = purchasedPrice;
this.quantity = quantity;
}
}

public enum OrderAction
{
Unknown, Buy, Sell
}

public sealed class Order
{
public string account { get; set; }
public string orderId { get; set; }
public OrderAction action { get; set; }
public Security security { get; set; }
public int quantity { get; set; }

}

a basic example for stock market.

I am trying to validate some things on the order..and for that I need to know if the Order.security.symbol is defined and what is is. This validation is what I want to add in the xBRE file.
I can access other fields.. but not the Order.security.symbol or order.security.currentPrice. I guess this is a very normal possible use of a validation .. isn't it?

Please let me know if you know how to access the subclass from xbre file.. and thanks!!
GeneralRe: Do you know how to access a class member from the xbre file? Pin
Suvabrata Roy10-Sep-12 8:57
professionalSuvabrata Roy10-Sep-12 8:57 
GeneralRe: Do you know how to access a class member from the xbre file? Pin
CodingABC10-Sep-12 14:29
CodingABC10-Sep-12 14:29 
GeneralMy vote of 5 Pin
Petr Kohout16-Jun-12 22:37
Petr Kohout16-Jun-12 22:37 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.