Click here to Skip to main content
15,885,366 members
Articles / Programming Languages / C# 5.0
Tip/Trick

Dotnet Simple Rule Engine

Rate me:
Please Sign up or sign in to vote.
4.88/5 (16 votes)
16 Jun 2015CPOL2 min read 66K   28   25
Dotnet Simple Rule Engine

Introduction

A Business Rule Engine is a software program which executes one or more business rules on behalf of other programs. This software provides convention, grammar or UI Interface which can be used by Business Person. They can define the rules without knowing the programming. Rules can be changed dynamically without changing the application code. I found Simple Rule Engine source code on http://www.csharpopensource.com/ site, downloaded the code, compiled it on Microsoft Dotnet version 4.0 to make it compatible with current
industry standard.

Background

A brief tutorial is available at http://simpleruleengine.tripod.com/.

I am going to provide the tutorials which help in understanding and sample program to use it.

Installation

We can install the compiled package using nuget Manager. It is now available as nuget package https://www.nuget.org/packages/SimpleRuleEngine.

To install it through nuget, use PM > Install-Package SimpleRuleEngine.

Business Requirement

  • Tax Calculator application which runs on the below business logic
  • If Gross Salary is less than Rs. 500,000/- for a year, there is no tax and Net Salary is same as Gross Salary.
  • If Gross Salary is between 500,000/- and 800,000/- for a year, tax will be 20 percent of Gross Salary. Net Salary will be equal to Gross Salary minus Tax.
  • If Gross Salary is equal or greater than Rs. 800,000/- for a year, tax will be 30 percent of Gross Salary and Net Salary will be equal to Gross Salary minus Tax.

Solution

The above problem can be achieved in different and multiple ways. But I am going to use the simple rule engine to achieve this.

  1. Open Visual Studio and create a sample Console application with name Tax Calculator.
  2. Add nuget package manager to add PM> Install-Package SimpleRuleEngine.
  3. Add one class RuleExecutor to execute the above rule.
    C#
    internal sealed class RuleExecutor
        {
            public void ExecuteTaxRules()
            {
                XmlDocument rules = new XmlDocument();
    
                string directory = AppDomain.CurrentDomain.BaseDirectory + @"\TaxCalculator.xml";
    
                rules.Load(directory);  
                //model
                XmlDocument model = new XmlDocument();
                model.LoadXml(@"<Employee><GrossSalary>900000</GrossSalary>
                <HRA>50000</HRA><Tax></Tax><NetSalary>
                </NetSalary></Employee>");
             
                ROM rom = Compiler.Compile(rules);
                rom.AddModel("Employee", model);
                rom.Evaluate();
                var tax = model["Employee"]["Tax"].InnerText;
                var NetSalary = model["Employee"]["NetSalary"].InnerText;
                var message = string.Format("Tax: {0} and Net take home salary :{1}", tax, NetSalary);
                Console.Write(message);
                Console.Read();
    }
    }
  4. We can define the rule in XML format and Simple Rule engine will execute, apply the rule and will give the output.
    XML
    <?xml version="1.0" encoding="utf-8" ?>
    <RuleEngine>
    
      <Rules>
        <Rule id="RuleNoTax" desc="Rule for no tax" chainable="true"  priority="100">
          <Condition><![CDATA[ GrossSalary < 500000 ]]></Condition>
          <Actions>
            <Evaluate factId="Tax" ><![CDATA[0]]></Evaluate>
            <Evaluate factId="NetSalary"><![CDATA[ GrossSalary ]]></Evaluate>
            <Execute factId="RuleMediumTax"/>
          </Actions>
        </Rule>
     
     
        <Rule id="RuleMediumTax" desc="Rule for Medium tax" chainable="true"   priority="19">
          <Condition><![CDATA[ (GrossSalary>=500000) AND (GrossSalary<800000)]]></Condition>
          <Actions>
            <Evaluate factId="Tax" priority="11"><![CDATA[ (GrossSalary *2/10)  ]]></Evaluate>
            <Evaluate factId="NetSalary" priority="1"><![CDATA[ (GrossSalary-Tax) ]]></Evaluate>
            <Execute factId="RuleHighTax"/>
          </Actions>
    
        </Rule>
        <Rule id="RuleHighTax" desc="Rule for High tax"  chainable="true"  priority="2">
          <Condition><![CDATA[ GrossSalary>=800000]]></Condition>
          <Actions>
            <Evaluate factId="Tax" priority="2" ><![CDATA[ GrossSalary*3/10 ]]></Evaluate>
            <Evaluate factId="NetSalary" priority="1"><![CDATA[ GrossSalary-Tax ]]></Evaluate>
          </Actions>
        </Rule>
        
      </Rules>
    
      <Facts>
        <Fact id="GrossSalary" desc="Gross Salary" type="double" modelId="Employee">
          <xpath><![CDATA[ number(Employee/GrossSalary) ]]></xpath>
        </Fact>
        <Fact id="HRA" desc="House Rent Allowance" type="double" modelId="Employee">
          <xpath><![CDATA[ Employee/HRA ]]></xpath>
        </Fact>
        <Fact id="Tax" desc="Tax" type="double" modelId="Employee">
          <xpath><![CDATA[ Employee/Tax ]]></xpath>
        </Fact>
        <Fact id="NetSalary" desc="Net Salary" type="double" modelId="Employee">
          <xpath><![CDATA[ Employee/NetSalary ]]></xpath>
        </Fact>
     
     
      </Facts>
    
    </RuleEngine>
  5. Now update the Program class as shown below:
    C#
    class Program
       {
           static void Main(string[] args)
           {
               var re = new RuleExecutor();
               re.ExecuteTaxRules();
           }
       }
    
  6. 6. Compile and run the program with different values of Gross salary element in XML model.

So here, today we learnt how we can put complex business logic separate from main program and execute it separately.

License

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


Written By
Architect
India India
Sarvesh Upadhyay is Technical Architect in Microsoft Technologies with 12 yrs of hands on experience on various domain like CRM, CMS, Inventory Management System, Telecome Billing, E-Commerce application, Retail etc.
He has indepth knowledge on Design Patterns, Asp.Net MVC, MVP , C#, JavaScript, Knockout, MS-SQL Server,Web Services,Web API, MSMQ, Saleslogix CRM, etc.

Comments and Discussions

 
QuestionIs anyone using this? Pin
RodneyLaJuan27-Dec-18 16:54
RodneyLaJuan27-Dec-18 16:54 
SuggestionRe: Is anyone using this? Pin
yogeshCJ11-Jun-19 23:15
yogeshCJ11-Jun-19 23:15 
QuestionNested Conditions in Simple Rule Engine Pin
Chirag Rajpal16-Oct-18 23:08
Chirag Rajpal16-Oct-18 23:08 
QuestionWhat does the priority mean in the rule xml? Pin
NITHIN SUHAS16-Sep-18 22:29
NITHIN SUHAS16-Sep-18 22:29 
QuestionCan we Use "Max" ? Pin
Member 1369910726-Feb-18 23:44
Member 1369910726-Feb-18 23:44 
QuestionSRE: How to use filter out in list, and, or Pin
Member 1163200523-Jun-17 0:16
Member 1163200523-Jun-17 0:16 
AnswerRe: SRE: How to use filter out in list, and, or Pin
Member 1298953021-Sep-17 0:00
Member 1298953021-Sep-17 0:00 
GeneralRe: SRE: How to use filter out in list, and, or Pin
Member 1298953021-Sep-17 0:06
Member 1298953021-Sep-17 0:06 
QuestionROM and Compiler.Compile Pin
Member 701715422-Jun-17 7:25
Member 701715422-Jun-17 7:25 
AnswerRe: ROM and Compiler.Compile Pin
Member 1163200522-Jun-17 23:56
Member 1163200522-Jun-17 23:56 
GeneralRe: ROM and Compiler.Compile Pin
Member 1039383325-Oct-17 21:31
Member 1039383325-Oct-17 21:31 
QuestionModel type Pin
Member 125952212-Mar-17 22:48
Member 125952212-Mar-17 22:48 
QuestionLoop in rule in XML Pin
Member 128450702-Feb-17 19:07
Member 128450702-Feb-17 19:07 
AnswerRe: Loop in rule in XML Pin
Member 125952213-Mar-17 0:24
Member 125952213-Mar-17 0:24 
QuestionSomething wrong... Pin
karan vidyut17-Nov-16 22:48
karan vidyut17-Nov-16 22:48 
QuestionRe: Something wrong... Pin
RodneyLaJuan27-Dec-18 17:02
RodneyLaJuan27-Dec-18 17:02 
AnswerRe: Something wrong... Pin
RodneyLaJuan29-Dec-18 8:38
RodneyLaJuan29-Dec-18 8:38 
QuestionNeeds documentation Pin
mattdunn617-Nov-16 10:24
mattdunn617-Nov-16 10:24 
AnswerRe: Needs documentation Pin
mattdunn617-Nov-16 10:43
mattdunn617-Nov-16 10:43 
QuestionHow to add OR Condition in rule Pin
Member 819864312-Aug-16 2:26
Member 819864312-Aug-16 2:26 
QuestionThis is not working Pin
Member 124530486-May-16 13:57
Member 124530486-May-16 13:57 
QuestionWould suggest learning about the system and terms if it was a professional project Pin
Member 1178413522-Jun-15 10:07
Member 1178413522-Jun-15 10:07 
QuestionXML Rule Repository Pin
Member 1104775117-Jun-15 9:28
Member 1104775117-Jun-15 9:28 
QuestionVery Interesting Pin
ugo.marchesini16-Jun-15 4:38
professionalugo.marchesini16-Jun-15 4:38 
Sure i'll use it Smile | :)

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.