Compare commits
3 Commits
84d580d858
...
5c265b0249
Author | SHA1 | Date |
---|---|---|
Abbas Cyclewala | 5c265b0249 | |
Abbas Cyclewala | 9b53a9aa3a | |
Abbas Cyclewala | 22353a38d0 |
|
@ -5,6 +5,8 @@ All notable changes to this project will be documented in this file.
|
|||
## [5.0.3]
|
||||
- Updated dependencies to latest
|
||||
- Fixed RulesEngine throwing exception when type name is same as input name
|
||||
- Added config to disable FastCompile for expressions
|
||||
- Added RuleParameter.Create method for better handling on types when value is null
|
||||
|
||||
## [5.0.2]
|
||||
- Fixed Scoped Params returning incorrect results in some corner case scenarios
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BenchmarkDotNet" Version="0.13.10" />
|
||||
<PackageReference Include="BenchmarkDotNet" Version="0.13.12" />
|
||||
<!--<PackageReference Include="RulesEngine" Version="3.0.2" />-->
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<RootNamespace>DemoApp.EFDataExample</RootNamespace>
|
||||
<AssemblyName>DemoApp.EFDataExample</AssemblyName>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.8" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.8" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.1" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<StartupObject>DemoApp.Program</StartupObject>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
@ -37,6 +37,8 @@ RulesEngine is a highly extensible library to build rule based system using C# e
|
|||
- [Steps to use a custom Action](#steps-to-use-a-custom-action)
|
||||
- [Standalone Expression Evaluator](#standalone-expression-evaluator)
|
||||
- [Usage](#usage-2)
|
||||
- [Settings](#settings)
|
||||
- [NestedRuleExecutionMode](#nestedruleexecutionmode)
|
||||
|
||||
|
||||
|
||||
|
@ -555,3 +557,30 @@ This will output "Hello World"
|
|||
|
||||
For more advanced usage, refer - https://dotnetfiddle.net/KSX8i0
|
||||
|
||||
## Settings
|
||||
RulesEngine allows you to pass optional `ReSettings` in constructor to specify certain configuration for RulesEngine.
|
||||
|
||||
Here are the all the options available:-
|
||||
|
||||
|
||||
| Property | Type | Default Value | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| `CustomTypes` | `Type[]` | N/A | Custom types to be used in rule expressions. |
|
||||
| `CustomActions` | `Dictionary<string, Func<ActionBase>>` | N/A | Custom actions that can be used in the rules. |
|
||||
| `EnableExceptionAsErrorMessage` | `bool` | `true` | If `true`, returns any exception occurred while rule execution as an error message. Otherwise, throws an exception. This setting is only applicable if `IgnoreException` is set to `false`. |
|
||||
| `IgnoreException` | `bool` | `false` | If `true`, it will ignore any exception thrown with rule compilation/execution. |
|
||||
| `EnableFormattedErrorMessage` | `bool` | `true` | Enables error message formatting. |
|
||||
| `EnableScopedParams` | `bool` | `true` | Enables global parameters and local parameters for rules. |
|
||||
| `IsExpressionCaseSensitive` | `bool` | `false` | Sets whether expressions are case sensitive. |
|
||||
| `AutoRegisterInputType` | `bool` | `true` | Auto registers input type in custom type to allow calling method on type. |
|
||||
| `NestedRuleExecutionMode` | `NestedRuleExecutionMode` | `All` | Sets the mode for nested rule execution. |
|
||||
| `CacheConfig` | `MemCacheConfig` | N/A | Configures the memory cache. |
|
||||
| `UseFastExpressionCompiler` | `bool` | `true` | Whether to use FastExpressionCompiler for rule compilation. |
|
||||
|
||||
|
||||
### NestedRuleExecutionMode
|
||||
|
||||
| Value | Description |
|
||||
| --- | --- |
|
||||
| `All` | Executes all nested rules. |
|
||||
| `Performance` | Skips nested rules whose execution does not impact parent rule's result. |
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"sdk": {
|
||||
"version": "6.0.0",
|
||||
"version": "8.0.0",
|
||||
"rollForward": "latestFeature",
|
||||
"allowPrerelease": false
|
||||
}
|
||||
|
|
|
@ -57,10 +57,19 @@ namespace RulesEngine.ExpressionBuilders
|
|||
}
|
||||
var expressionBody = new List<Expression>() { e };
|
||||
var wrappedExpression = WrapExpression<T>(expressionBody, parameterExpressions, new ParameterExpression[] { });
|
||||
return wrappedExpression.CompileFast();
|
||||
return CompileExpression(wrappedExpression);
|
||||
|
||||
}
|
||||
|
||||
private Func<object[], T> CompileExpression<T>(Expression<Func<object[], T>> expression)
|
||||
{
|
||||
if(_reSettings.UseFastExpressionCompiler)
|
||||
{
|
||||
return expression.CompileFast();
|
||||
}
|
||||
return expression.Compile();
|
||||
}
|
||||
|
||||
private Expression<Func<object[], T>> WrapExpression<T>(List<Expression> expressionList, ParameterExpression[] parameters, ParameterExpression[] variables)
|
||||
{
|
||||
var argExp = Expression.Parameter(typeof(object[]), "args");
|
||||
|
@ -77,7 +86,7 @@ namespace RulesEngine.ExpressionBuilders
|
|||
{
|
||||
ruleExpParams = ruleExpParams ?? new RuleExpressionParameter[] { };
|
||||
var expression = CreateDictionaryExpression(ruleParams, ruleExpParams);
|
||||
return expression.CompileFast();
|
||||
return CompileExpression(expression);
|
||||
}
|
||||
|
||||
public T Evaluate<T>(string expression, RuleParameter[] ruleParams)
|
||||
|
|
|
@ -27,7 +27,8 @@ namespace RulesEngine.Models
|
|||
CacheConfig = reSettings.CacheConfig;
|
||||
IsExpressionCaseSensitive = reSettings.IsExpressionCaseSensitive;
|
||||
AutoRegisterInputType = reSettings.AutoRegisterInputType;
|
||||
}
|
||||
UseFastExpressionCompiler = reSettings.UseFastExpressionCompiler;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
|
@ -79,6 +80,10 @@ namespace RulesEngine.Models
|
|||
/// </summary>
|
||||
public NestedRuleExecutionMode NestedRuleExecutionMode { get; set; } = NestedRuleExecutionMode.All;
|
||||
public MemCacheConfig CacheConfig { get; set; }
|
||||
/// <summary>
|
||||
/// Whether to use FastExpressionCompiler for rule compilation
|
||||
/// </summary>
|
||||
public bool UseFastExpressionCompiler { get; set; } = true;
|
||||
}
|
||||
|
||||
public enum NestedRuleExecutionMode
|
||||
|
|
|
@ -17,10 +17,13 @@ namespace RulesEngine.Models
|
|||
Init(name, Value?.GetType());
|
||||
}
|
||||
|
||||
internal RuleParameter(string name, Type type)
|
||||
|
||||
internal RuleParameter(string name, Type type,object value = null)
|
||||
{
|
||||
Value = Utils.GetTypedObject(value);
|
||||
Init(name, type);
|
||||
}
|
||||
|
||||
public Type Type { get; private set; }
|
||||
public string Name { get; private set; }
|
||||
public object Value { get; private set; }
|
||||
|
@ -33,5 +36,13 @@ namespace RulesEngine.Models
|
|||
ParameterExpression = Expression.Parameter(Type, Name);
|
||||
}
|
||||
|
||||
public static RuleParameter Create<T>(string name, T value)
|
||||
{
|
||||
var typedValue = Utils.GetTypedObject(value);
|
||||
var type = typedValue?.GetType() ?? typeof(T);
|
||||
return new RuleParameter(name,type,value);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net6.0;netstandard2.0</TargetFrameworks>
|
||||
<TargetFrameworks>net8.0;net6.0;netstandard2.0</TargetFrameworks>
|
||||
<Version>5.0.3</Version>
|
||||
<Copyright>Copyright (c) Microsoft Corporation.</Copyright>
|
||||
<PackageLicenseFile>LICENSE</PackageLicenseFile>
|
||||
|
@ -34,13 +34,14 @@
|
|||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FastExpressionCompiler" Version="4.0.1" />
|
||||
<PackageReference Include="FluentValidation" Version="11.8.1" />
|
||||
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
|
||||
<PackageReference Include="FluentValidation" Version="11.9.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="System.Linq" Version="4.3.0" />
|
||||
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.3.7" />
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
|
||||
<PackageReference Include="System.Threading.Tasks.Extensions" Version="4.5.4" />
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="All" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
|
||||
<PackageReference Include="Microsoft.CSharp" Version="4.7.0"/>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -338,8 +338,9 @@ namespace RulesEngine.UnitTest
|
|||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("rules4.json")]
|
||||
public async Task RulesEngine_Execute_Rule_For_Nested_Rule_Params_Returns_Success(string ruleFileName)
|
||||
[InlineData("rules4.json", true)]
|
||||
[InlineData("rules4.json", false)]
|
||||
public async Task RulesEngine_Execute_Rule_For_Nested_Rule_Params_Returns_Success(string ruleFileName,bool fastExpressionEnabled)
|
||||
{
|
||||
var inputs = GetInputs4();
|
||||
|
||||
|
@ -359,7 +360,9 @@ namespace RulesEngine.UnitTest
|
|||
}
|
||||
|
||||
var fileData = File.ReadAllText(files[0]);
|
||||
var bre = new RulesEngine(JsonConvert.DeserializeObject<Workflow[]>(fileData), null);
|
||||
var bre = new RulesEngine(JsonConvert.DeserializeObject<Workflow[]>(fileData), new ReSettings {
|
||||
UseFastExpressionCompiler = fastExpressionEnabled
|
||||
});
|
||||
var result = await bre.ExecuteAllRulesAsync("inputWorkflow", ruleParams?.ToArray());
|
||||
var ruleResult = result?.FirstOrDefault(r => string.Equals(r.Rule.RuleName, "GiveDiscount10", StringComparison.OrdinalIgnoreCase));
|
||||
Assert.True(ruleResult.IsSuccess);
|
||||
|
|
|
@ -3,14 +3,8 @@
|
|||
|
||||
using Newtonsoft.Json.Linq;
|
||||
using RulesEngine.ExpressionBuilders;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace RulesEngine.UnitTest.RuleExpressionParserTests
|
||||
{
|
||||
|
@ -59,5 +53,17 @@ namespace RulesEngine.UnitTest.RuleExpressionParserTests
|
|||
|
||||
Assert.Equal("helloworld", value3);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(false)]
|
||||
public void TestExpressionWithDifferentCompilerSettings(bool fastExpressionEnabled){
|
||||
var ruleParser = new RuleExpressionParser(new Models.ReSettings() { UseFastExpressionCompiler = fastExpressionEnabled });
|
||||
|
||||
decimal? d1 = null;
|
||||
var result = ruleParser.Evaluate<bool>("d1 < 20", new[] { Models.RuleParameter.Create("d1", d1) });
|
||||
Assert.False(result);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<SignAssembly>True</SignAssembly>
|
||||
<AssemblyOriginatorKeyFile>..\..\signing\RulesEngine-publicKey.snk</AssemblyOriginatorKeyFile>
|
||||
<DelaySign>True</DelaySign>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AutoFixture" Version="4.18.0" />
|
||||
<PackageReference Include="AutoFixture" Version="4.18.1" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
|
||||
<PackageReference Include="Moq" Version="4.20.69" />
|
||||
<PackageReference Include="System.Text.Json" Version="7.0.3" />
|
||||
<PackageReference Include="xunit" Version="2.6.2" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.4">
|
||||
<PackageReference Include="Moq" Version="4.20.70" />
|
||||
<PackageReference Include="System.Text.Json" Version="8.0.1" />
|
||||
<PackageReference Include="xunit" Version="2.6.5" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.6">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
|
|
Loading…
Reference in New Issue