Skip to content

Commit

Permalink
Users/abbasc52/doc updates (#555)
Browse files Browse the repository at this point in the history
* added custom type injection in docs

* updated expression parser to support null Resettings and added standalone evaluator sample

* fixed missing bracket
  • Loading branch information
abbasc52 authored Nov 26, 2023
1 parent b783602 commit 9bcf4f3
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 16 deletions.
88 changes: 85 additions & 3 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ RulesEngine is a highly extensible library to build rule based system using C# e
- Extending expression via custom class/type injection
- Scoped parameters
- Post rule execution actions
- Standalone expression evaluator

**Table Of Content**
- [Installation](#installation)
Expand All @@ -18,11 +19,13 @@ RulesEngine is a highly extensible library to build rule based system using C# e
- [Execute the workflow rules with input:](#execute-the-workflow-rules-with-input)
- [Using custom names for inputs](#using-custom-names-for-inputs)
- [C# Expression support](#c-expression-support)
- [Extending expression via custom class/type injection](#extending-expression-via-custom-classtype-injection)
- [Example](#example)
- [ScopedParams](#scopedparams)
- [GlobalParams](#globalparams)
- [Example](#example)
- [LocalParams](#localparams)
- [Example](#example-1)
- [LocalParams](#localparams)
- [Example](#example-2)
- [Referencing ScopedParams in other ScopedParams](#referencing-scopedparams-in-other-scopedparams)
- [Post rule execution actions](#post-rule-execution-actions)
- [Inbuilt Actions](#inbuilt-actions)
Expand All @@ -32,6 +35,8 @@ RulesEngine is a highly extensible library to build rule based system using C# e
- [Usage](#usage-1)
- [Custom Actions](#custom-actions)
- [Steps to use a custom Action](#steps-to-use-a-custom-action)
- [Standalone Expression Evaluator](#standalone-expression-evaluator)
- [Usage](#usage-2)



Expand Down Expand Up @@ -123,6 +128,59 @@ For more details on supported expression language refer - [expression language](
For supported linq operations refer - [sequence operators](https://dynamic-linq.net/expression-language#sequence-operators)


## Extending expression via custom class/type injection
Although RulesEngine supports C# expressions, you may need to perform more complex operation.

RulesEngine supports injecting custom classes/types via `ReSettings` which can allow you to call properties and methods of your custom class in expressions

### Example
Create a custom static class
```c#
using System;
using System.Linq;

namespace RE.HelperFunctions
{
public static class Utils
{
public static bool CheckContains(string check, string valList)
{
if (String.IsNullOrEmpty(check) || String.IsNullOrEmpty(valList))
return false;

var list = valList.Split(',').ToList();
return list.Contains(check);
}
}
}
```

Add it in your ReSettings and pass in RulesEngine constructor

```c#
var reSettings = new ReSettings{
CustomTypes = new Type[] { typeof(Utils) }
}

var rulesEngine = new RulesEngine.RulesEngine(workflowRules,reSettings);
```

With this you can call Utils class in your Rules

```json
{
"WorkflowName": "DiscountWithCustomInputNames",
"Rules": [
{
"RuleName": "GiveDiscount10",
"Expression": "Utils.CheckContains(input1.country, \"india,usa,canada,France\") == true"
}
]
}

```


## ScopedParams
Sometimes Rules can get very long and complex, scopedParams allow users to replace an expression in rule with an alias making it easier to maintain rule.

Expand Down Expand Up @@ -471,5 +529,29 @@ Actions can have async code as well
}
```

## Standalone Expression Evaluator
If you are not looking for a full fledged RulesEngine and need only an expression evaluator. RulesEngine offers `RuleExpressionParser` which handles expression parsing and evaluation.

### Usage
```c#
using System;
using RulesEngine.Models;
using RulesEngine.ExpressionBuilders;

public class Program
{
public static void Main()
{
var reParser = new RuleExpressionParser(new ReSettings());
var result = reParser.Evaluate<string>("a+b", new RuleParameter[]{
new RuleParameter("a","Hello "),
new RuleParameter("b","World")
});
Console.WriteLine(result);
}
}
```
This will output "Hello World"

For more advanced usage, refer - https://dotnetfiddle.net/KSX8i0
_For more details please check out [Rules Engine Wiki](https://github.com/microsoft/RulesEngine/wiki)._
4 changes: 2 additions & 2 deletions src/RulesEngine/ExpressionBuilders/RuleExpressionParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ public class RuleExpressionParser
private readonly ReSettings _reSettings;
private readonly IDictionary<string, MethodInfo> _methodInfo;

public RuleExpressionParser(ReSettings reSettings)
public RuleExpressionParser(ReSettings reSettings = null)
{
_reSettings = reSettings;
_reSettings = reSettings ?? new ReSettings();
_methodInfo = new Dictionary<string, MethodInfo>();
PopulateMethodInfo();
}
Expand Down
22 changes: 11 additions & 11 deletions test/RulesEngine.UnitTest/TypedClassTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,11 +120,11 @@ public async Task TypedClassInputSameNameAsTypeTest()
var re = new RulesEngine(reSettings);
re.AddWorkflow(workflow);

var param = new Transazione {
var param = new Transazione {
Attori = new List<Attore>{
new Attore{
RuoloAttore = RuoloAttore.B,

RuoloAttore = RuoloAttore.B,

},
new Attore {
RuoloAttore = RuoloAttore.C
Expand All @@ -137,9 +137,9 @@ public async Task TypedClassInputSameNameAsTypeTest()

Assert.All(result, (res) => Assert.True(res.IsSuccess));

}


}


[Fact]
public async Task TypedClassBothAccessibleTestWhenCaseInsensitive()
{
Expand All @@ -163,8 +163,8 @@ public async Task TypedClassBothAccessibleTestWhenCaseInsensitive()
Expression = "transazione.Attori != null",
},
new() {
RuleName = "Static FieldTest",
Expression = "Transazione.StaticProperty == \"Hello\""
RuleName = "Static FieldTest",
Expression = "Transazione.StaticProperty == \"Hello\""
}
}
};
Expand All @@ -177,11 +177,11 @@ public async Task TypedClassBothAccessibleTestWhenCaseInsensitive()
var re = new RulesEngine(reSettings);
re.AddWorkflow(workflow);

var param = new Transazione {
var param = new Transazione {
Attori = new List<Attore>{
new Attore{
RuoloAttore = RuoloAttore.B,

RuoloAttore = RuoloAttore.B,

},
new Attore {
RuoloAttore = RuoloAttore.C
Expand Down

0 comments on commit 9bcf4f3

Please sign in to comment.