JsonRulesEngine 0.0.1

Suggested Alternatives

JsonRuleEngine 0.0.2

Additional Details

package name change

dotnet add package JsonRulesEngine --version 0.0.1
NuGet\Install-Package JsonRulesEngine -Version 0.0.1
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="JsonRulesEngine" Version="0.0.1" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add JsonRulesEngine --version 0.0.1
#r "nuget: JsonRulesEngine, 0.0.1"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install JsonRulesEngine as a Cake Addin
#addin nuget:?package=JsonRulesEngine&version=0.0.1

// Install JsonRulesEngine as a Cake Tool
#tool nuget:?package=JsonRulesEngine&version=0.0.1

CSharp - Json Rules Engine

.NET Core CI/CD codecov

This project inspired originally from json-rules-engine project. Even there are many similarities, This is not a complete PORT of 'json-rules-engine' Still has lots of works to do.

Installation

Install using the JsonRulesEngine NuGet package:

dotnet add package JsonRulesEngine --version 0.0.1

Basic Usage

var events = e.Execute(incomingObj);


var incomingJson= `{
    "age": 19,
    "line-item-names": [
        "banana",
        "apple"
    ],
    "amount":300
}`

JObject incomingFact = //Read Json Object

var engine = new Engine();
engine.AddRule(ruleJson);// checkout Rules section
var events = e.Execute(ruleJson);
foreach (var @event in events)
    {
        if (@event is DiscountEvent)
        {
            var discountEvent = (DiscountEvent)@event;
            Console.WriteLine("DiscountEvent with amount : {0}", discountEvent.amount);
        }
        
    }

Rules

Rule is a json object it contains two main properties. conditions and event

//If age is above 18 and total transaction amount is less than 1000 and ('line-item-names' list contains 'banana' or 'amount' is in range (50,300])
{
    "conditions": {
        "all": [
            {
                "fact": "age",
                "operator": "greaterThan",
                "value": 18
            },
            {
                "fact":"total-transaction-amount",//DynamicFact
                "params":{
                    "startDate":"2020-12-12T10:00:00",
                    "endDate":"2021-12-12T10:00:00",
                },
                "operator":"lessThan",
                "value":1000
            },
            {
                "any": [
                    {
                        "fact": "line-item-names",
                        "operator": "contain",
                        "value": "banana"
                    },
                    {
                        "fact": "amount",
                        "operator": "in-range",//CustomOperator
                        "value": [50,300]
                    }
                ]
            }
        ]
    },
    "event": {
        "type": "discount",
        "amount": 100
    }
}

Operators

Engine has couple of default operators:

  • equal makes string comparison
  • greaterThan float comparison
  • greaterThanInclusive float comparison
  • lessThan float comparison
  • lessThanThanInclusive float comparison
  • in string array comparison
  • contain string array comparison

Custom Operators

You could also define your custom operators like following. Declare a type inherited from Operator<L,R>, engine will resolve it automatically.

public class InRange : Operator<float, List<float>>
{
    public override string Name => "in-range";

    public override bool Evaluate(float left, List<float> right) // range(1,3]
    {
        float upperBound = right.Last();
        float lowerBound = right.First();
        if (left > lowerBound && left <= upperBound)
        {
            return true;
        }
        return false;
    }
}

DynamicFact

If your incomingJson unable to contain certain information. You can inherit a class from DynamicFact to achive this. declare it anywhere you want. engine will resolve it for you.

Example total-transcation-amount:

 public class TotalTransactionAmount : DynamicFact
    {
        public override string Name => "total-transaction-amount";

        public override object Calculate(ExecutionContext context, dynamic @params)
        {
            var productToken = context.FactValue("products");//able to get fact value from context
                                                             //it will not compute if fact value if it has already computed beforehand
            var products = productToken.ToObject<List<string>>();

            DateTime startDate = @params["startDate"];
            DateTime endDate = @params["endDate"];
            // go anywhere you want
            return 100;
        }
    }

RuleEvent

Engine should know the type of an RuleEvent in order to cast it to an instane. Just inherit a class from RuleEvent, engine will resolve types from assembly.

 public class DiscountEvent : RuleEvent
    {
        public override string Name => "discount";
        public float amount;
    }

TODOS

  • Fact priorities
  • Rule priorities
  • Unit Tests
  • Documentation
  • Nuget Package
  • CD/CI
  • Async Execution and Event Handles
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp3.1 is compatible. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
0.0.1 462 2/21/2021