diff --git a/.github/workflows/dotnetcore-build.yml b/.github/workflows/dotnetcore-build.yml
index c4b0524..52de750 100644
--- a/.github/workflows/dotnetcore-build.yml
+++ b/.github/workflows/dotnetcore-build.yml
@@ -16,21 +16,21 @@ jobs:
- name: Setup .NET Core
uses: actions/setup-dotnet@v1
with:
- dotnet-version: 3.1
+ dotnet-version: 3.1.101
- name: Install minicover
run: dotnet tool install --global minicover --version 3.0.6
- name: Install dependencies
- run: dotnet restore RulesEngine.sln
+ run: dotnet restore src/RulesEngine/RulesEngine.sln
- name: Build
- run: dotnet build RulesEngine.sln --configuration Release --no-restore
+ run: dotnet build src/RulesEngine/RulesEngine.sln --configuration Release --no-restore
- name: Instrument
run: minicover instrument
- name: Test
- run: dotnet test RulesEngine.sln --no-build --configuration Release --verbosity m
+ run: dotnet test src/RulesEngine/RulesEngine.sln --no-build --configuration Release --verbosity m
- name: Uninstrument
run: minicover uninstrument
- name: Report
- run: minicover report --threshold 95
+ run: minicover report --threshold 80
if: ${{ github.event_name == 'pull_request' }}
- name: Report coveralls
run: minicover coverallsreport --repo-token ${{ secrets.COVERALLS_TOKEN }} --branch master
diff --git a/.vscode/launch.json b/.vscode/launch.json
deleted file mode 100644
index 6f691ce..0000000
--- a/.vscode/launch.json
+++ /dev/null
@@ -1,27 +0,0 @@
-{
- // Use IntelliSense to find out which attributes exist for C# debugging
- // Use hover for the description of the existing attributes
- // For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
- "version": "0.2.0",
- "configurations": [
- {
- "name": ".NET Core Launch (console)",
- "type": "coreclr",
- "request": "launch",
- "preLaunchTask": "build",
- // If you have changed target frameworks, make sure to update the program path.
- "program": "${workspaceFolder}/demo/DemoApp/bin/Debug/netcoreapp3.1/DemoApp.dll",
- "args": [],
- "cwd": "${workspaceFolder}/demo/DemoApp",
- // For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
- "console": "internalConsole",
- "stopAtEntry": false
- },
- {
- "name": ".NET Core Attach",
- "type": "coreclr",
- "request": "attach",
- "processId": "${command:pickProcess}"
- }
- ]
-}
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
deleted file mode 100644
index 7870888..0000000
--- a/.vscode/settings.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "dotnetCoreExplorer.searchpatterns": "test/**/bin/Debug/netcoreapp*/*.{dll,exe,json}"
-}
\ No newline at end of file
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
deleted file mode 100644
index 94770e3..0000000
--- a/.vscode/tasks.json
+++ /dev/null
@@ -1,42 +0,0 @@
-{
- "version": "2.0.0",
- "tasks": [
- {
- "label": "build",
- "command": "dotnet",
- "type": "process",
- "args": [
- "build",
- "${workspaceFolder}/demo/DemoApp/DemoApp.csproj",
- "/property:GenerateFullPaths=true",
- "/consoleloggerparameters:NoSummary"
- ],
- "problemMatcher": "$msCompile"
- },
- {
- "label": "publish",
- "command": "dotnet",
- "type": "process",
- "args": [
- "publish",
- "${workspaceFolder}/demo/DemoApp/DemoApp.csproj",
- "/property:GenerateFullPaths=true",
- "/consoleloggerparameters:NoSummary"
- ],
- "problemMatcher": "$msCompile"
- },
- {
- "label": "watch",
- "command": "dotnet",
- "type": "process",
- "args": [
- "watch",
- "run",
- "${workspaceFolder}/demo/DemoApp/DemoApp.csproj",
- "/property:GenerateFullPaths=true",
- "/consoleloggerparameters:NoSummary"
- ],
- "problemMatcher": "$msCompile"
- }
- ]
-}
\ No newline at end of file
diff --git a/demo/DemoApp/DemoApp.csproj b/demo/DemoApp/DemoApp.csproj
index fc7049e..37c2e70 100644
--- a/demo/DemoApp/DemoApp.csproj
+++ b/demo/DemoApp/DemoApp.csproj
@@ -8,7 +8,7 @@
-
+
diff --git a/global.json b/global.json
index 1009c7f..0d92626 100644
--- a/global.json
+++ b/global.json
@@ -1,7 +1,6 @@
{
"sdk": {
"version": "3.1.101",
- "rollForward": "latestFeature",
- "allowPrerelease": false
+ "rollForward": "latestFeature"
}
}
\ No newline at end of file
diff --git a/src/RulesEngine/HelperFunctions/Helpers.cs b/src/RulesEngine/HelperFunctions/Helpers.cs
deleted file mode 100644
index ecc30f7..0000000
--- a/src/RulesEngine/HelperFunctions/Helpers.cs
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-
-using RulesEngine.Models;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Linq.Expressions;
-
-namespace RulesEngine.HelperFunctions
-{
- ///
- /// Helpers
- ///
- internal static class Helpers
- {
- internal static RuleFunc ToResultTree(Rule rule, IEnumerable childRuleResults, RuleFunc isSuccessFunc, string exceptionMessage = "")
- {
- return (inputs) => new RuleResultTree
- {
- Rule = rule,
- Input = inputs.FirstOrDefault(),
- IsSuccess = isSuccessFunc(inputs),
- ChildResults = childRuleResults,
- ExceptionMessage = exceptionMessage
- };
- }
-
- ///
- /// To the result tree error messages
- ///
- /// ruleResultTree
- /// ruleResultMessage
- internal static void ToResultTreeMessages(RuleResultTree ruleResultTree, ref RuleResultMessage ruleResultMessage)
- {
- if (ruleResultTree.ChildResults != null)
- {
- GetChildRuleMessages(ruleResultTree.ChildResults, ref ruleResultMessage);
- }
- else
- {
- if (!ruleResultTree.IsSuccess)
- {
- string errMsg = ruleResultTree.Rule.ErrorMessage;
- errMsg = string.IsNullOrEmpty(errMsg) ? $"Error message does not configured for {ruleResultTree.Rule.RuleName}" : errMsg;
-
- if (ruleResultTree.Rule.ErrorType == ErrorType.Error && !ruleResultMessage.ErrorMessages.Contains(errMsg))
- {
- ruleResultMessage.ErrorMessages.Add(errMsg);
- }
- else if (ruleResultTree.Rule.ErrorType == ErrorType.Warning && !ruleResultMessage.WarningMessages.Contains(errMsg))
- {
- ruleResultMessage.WarningMessages.Add(errMsg);
- }
- }
- }
- }
-
- ///
- /// To get the child error message recersivly
- ///
- /// childResultTree
- /// ruleResultMessage
- private static void GetChildRuleMessages(IEnumerable childResultTree, ref RuleResultMessage ruleResultMessage)
- {
- foreach (var item in childResultTree)
- {
- ToResultTreeMessages(item, ref ruleResultMessage);
- }
- }
- }
-}
diff --git a/src/RulesEngine/Models/CompiledRuleParam.cs b/src/RulesEngine/Models/CompiledRuleParam.cs
deleted file mode 100644
index 4e470a0..0000000
--- a/src/RulesEngine/Models/CompiledRuleParam.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Diagnostics.CodeAnalysis;
-using System.Text;
-
-namespace RulesEngine.Models
-{
- [ExcludeFromCodeCoverage]
- internal class CompiledRuleParam
- {
- internal string Name { get; set; }
- internal IEnumerable CompiledParameters { get; set; }
- internal IEnumerable RuleParameters { get; set; }
- }
-}
diff --git a/src/RulesEngine/Models/RuleDelegate.cs b/src/RulesEngine/Models/RuleDelegate.cs
deleted file mode 100644
index df6ebeb..0000000
--- a/src/RulesEngine/Models/RuleDelegate.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-
-namespace RulesEngine.Models
-{
- public delegate T RuleFunc(params object[] param);
-
-}
diff --git a/RulesEngine.sln b/src/RulesEngine/RulesEngine.sln
similarity index 89%
rename from RulesEngine.sln
rename to src/RulesEngine/RulesEngine.sln
index f984879..bb5e076 100644
--- a/RulesEngine.sln
+++ b/src/RulesEngine/RulesEngine.sln
@@ -3,11 +3,11 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29123.89
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RulesEngine", "src\RulesEngine\\RulesEngine.csproj", "{CD4DFE6A-083B-478E-8377-77F474833E30}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RulesEngine", "RulesEngine\RulesEngine.csproj", "{CD4DFE6A-083B-478E-8377-77F474833E30}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RulesEngine.UnitTest", "test\RulesEngine.UnitTest\RulesEngine.UnitTest.csproj", "{50E0C2A5-E2C8-4B12-8C0E-B69F698A82BF}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RulesEngine.UnitTest", "..\..\test\RulesEngine.UnitTest\RulesEngine.UnitTest.csproj", "{50E0C2A5-E2C8-4B12-8C0E-B69F698A82BF}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DemoApp", "demo\DemoApp\DemoApp.csproj", "{57BB8C07-799A-4F87-A7CC-D3D3F694DD02}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DemoApp", "..\..\demo\DemoApp\DemoApp.csproj", "{57BB8C07-799A-4F87-A7CC-D3D3F694DD02}"
ProjectSection(ProjectDependencies) = postProject
{CD4DFE6A-083B-478E-8377-77F474833E30} = {CD4DFE6A-083B-478E-8377-77F474833E30}
EndProjectSection
diff --git a/src/RulesEngine/CustomTypeProvider.cs b/src/RulesEngine/RulesEngine/CustomTypeProvider.cs
similarity index 100%
rename from src/RulesEngine/CustomTypeProvider.cs
rename to src/RulesEngine/RulesEngine/CustomTypeProvider.cs
diff --git a/src/RulesEngine/Exceptions/RuleValidationException.cs b/src/RulesEngine/RulesEngine/Exceptions/RuleValidationException.cs
similarity index 100%
rename from src/RulesEngine/Exceptions/RuleValidationException.cs
rename to src/RulesEngine/RulesEngine/Exceptions/RuleValidationException.cs
diff --git a/src/RulesEngine/ExpressionBuilders/LambdaExpressionBuilder.cs b/src/RulesEngine/RulesEngine/ExpressionBuilders/LambdaExpressionBuilder.cs
similarity index 71%
rename from src/RulesEngine/ExpressionBuilders/LambdaExpressionBuilder.cs
rename to src/RulesEngine/RulesEngine/ExpressionBuilders/LambdaExpressionBuilder.cs
index 64c1bb7..3a93b78 100644
--- a/src/RulesEngine/ExpressionBuilders/LambdaExpressionBuilder.cs
+++ b/src/RulesEngine/RulesEngine/ExpressionBuilders/LambdaExpressionBuilder.cs
@@ -24,22 +24,21 @@ namespace RulesEngine.ExpressionBuilders
{
_reSettings = reSettings;
}
- internal override RuleFunc BuildExpressionForRule(Rule rule, IEnumerable typeParamExpressions)
+ internal override Expression> BuildExpressionForRule(Rule rule, IEnumerable typeParamExpressions, ParameterExpression ruleInputExp)
{
try
{
var config = new ParsingConfig { CustomTypeProvider = new CustomTypeProvider(_reSettings.CustomTypes) };
- var e = DynamicExpressionParser.ParseLambda(config, true, typeParamExpressions.ToArray(),typeof(bool), rule.Expression);
- var ruleDelegate = e.Compile();
- bool func(object[] paramList) => (bool)ruleDelegate.DynamicInvoke(paramList);
- return Helpers.ToResultTree(rule, null, func);
+ var e = DynamicExpressionParser.ParseLambda(config, typeParamExpressions.ToArray(), null, rule.Expression);
+ var body = (BinaryExpression)e.Body;
+ return Helpers.ToResultTreeExpression(rule, null, body, typeParamExpressions, ruleInputExp);
}
- catch (Exception ex)
+ catch (Exception ex)
{
- bool func(object[] param) => false;
+ var binaryExpression = Expression.And(Expression.Constant(true), Expression.Constant(false));
var exceptionMessage = ex.Message;
- return Helpers.ToResultTree(rule, null, func, exceptionMessage);
- }
+ return Helpers.ToResultTreeExpression(rule, null, binaryExpression, typeParamExpressions, ruleInputExp, exceptionMessage);
+ }
}
/// Builds the expression for rule parameter.
diff --git a/src/RulesEngine/ExpressionBuilders/RuleExpressionBuilderBase.cs b/src/RulesEngine/RulesEngine/ExpressionBuilders/RuleExpressionBuilderBase.cs
similarity index 86%
rename from src/RulesEngine/ExpressionBuilders/RuleExpressionBuilderBase.cs
rename to src/RulesEngine/RulesEngine/ExpressionBuilders/RuleExpressionBuilderBase.cs
index ec1b05b..88a6da7 100644
--- a/src/RulesEngine/ExpressionBuilders/RuleExpressionBuilderBase.cs
+++ b/src/RulesEngine/RulesEngine/ExpressionBuilders/RuleExpressionBuilderBase.cs
@@ -20,7 +20,7 @@ namespace RulesEngine.ExpressionBuilders
/// The type parameter expressions.
/// The rule input exp.
/// Expression type
- internal abstract RuleFunc BuildExpressionForRule(Rule rule, IEnumerable typeParameterExpressions);
+ internal abstract Expression> BuildExpressionForRule(Rule rule, IEnumerable typeParamExpressions, ParameterExpression ruleInputExp);
/// Builds the expression for rule parameter.
/// The rule.
diff --git a/src/RulesEngine/Extensions/ListofRuleResultTreeExtension.cs b/src/RulesEngine/RulesEngine/Extensions/ListofRuleResultTreeExtension.cs
similarity index 100%
rename from src/RulesEngine/Extensions/ListofRuleResultTreeExtension.cs
rename to src/RulesEngine/RulesEngine/Extensions/ListofRuleResultTreeExtension.cs
diff --git a/src/RulesEngine/HelperFunctions/Constants.cs b/src/RulesEngine/RulesEngine/HelperFunctions/Constants.cs
similarity index 100%
rename from src/RulesEngine/HelperFunctions/Constants.cs
rename to src/RulesEngine/RulesEngine/HelperFunctions/Constants.cs
diff --git a/src/RulesEngine/HelperFunctions/ExpressionUtils.cs b/src/RulesEngine/RulesEngine/HelperFunctions/ExpressionUtils.cs
similarity index 100%
rename from src/RulesEngine/HelperFunctions/ExpressionUtils.cs
rename to src/RulesEngine/RulesEngine/HelperFunctions/ExpressionUtils.cs
diff --git a/src/RulesEngine/RulesEngine/HelperFunctions/Helpers.cs b/src/RulesEngine/RulesEngine/HelperFunctions/Helpers.cs
new file mode 100644
index 0000000..0446b44
--- /dev/null
+++ b/src/RulesEngine/RulesEngine/HelperFunctions/Helpers.cs
@@ -0,0 +1,122 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using RulesEngine.Models;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Linq.Expressions;
+
+namespace RulesEngine.HelperFunctions
+{
+ ///
+ /// Helpers
+ ///
+ internal static class Helpers
+ {
+ ///
+ /// To the result tree expression.
+ ///
+ /// The rule.
+ /// The child rule results.
+ /// The is success exp.
+ /// The type parameter expressions.
+ /// The rule input exp.
+ /// Expression of func
+ internal static Expression> ToResultTreeExpression(Rule rule, IEnumerable childRuleResults, BinaryExpression isSuccessExp, IEnumerable typeParamExpressions, ParameterExpression ruleInputExp, string exceptionMessage = "")
+ {
+ var memberInit = ToResultTree(rule, childRuleResults, isSuccessExp, typeParamExpressions, null, exceptionMessage);
+ var lambda = Expression.Lambda>(memberInit, new[] { ruleInputExp });
+ return lambda;
+ }
+
+ ///
+ /// To the result tree member expression
+ ///
+ /// The rule.
+ /// The child rule results.
+ /// The is success exp.
+ /// The child rule results block expression.
+ ///
+ internal static MemberInitExpression ToResultTree(Rule rule, IEnumerable childRuleResults, BinaryExpression isSuccessExp, IEnumerable typeParamExpressions, BlockExpression childRuleResultsblockexpr, string exceptionMessage = "")
+ {
+ var createdType = typeof(RuleResultTree);
+ var ctor = Expression.New(createdType);
+
+ var ruleProp = createdType.GetProperty(nameof(RuleResultTree.Rule));
+ var isSuccessProp = createdType.GetProperty(nameof(RuleResultTree.IsSuccess));
+ var childResultProp = createdType.GetProperty(nameof(RuleResultTree.ChildResults));
+ var inputProp = createdType.GetProperty(nameof(RuleResultTree.Input));
+ var exceptionProp = createdType.GetProperty(nameof(RuleResultTree.ExceptionMessage));
+
+ var rulePropBinding = Expression.Bind(ruleProp, Expression.Constant(rule));
+ var isSuccessPropBinding = Expression.Bind(isSuccessProp, isSuccessExp);
+ var inputBinding = Expression.Bind(inputProp, typeParamExpressions.FirstOrDefault());
+ var exceptionBinding = Expression.Bind(exceptionProp, Expression.Constant(exceptionMessage));
+
+ MemberInitExpression memberInit;
+
+ if (childRuleResults != null)
+ {
+ var ruleResultTreeArr = Expression.NewArrayInit(typeof(RuleResultTree), childRuleResults);
+
+ var childResultPropBinding = Expression.Bind(childResultProp, ruleResultTreeArr);
+ memberInit = Expression.MemberInit(ctor, new[] { rulePropBinding, isSuccessPropBinding, childResultPropBinding, inputBinding, exceptionBinding });
+ }
+ else if (childRuleResultsblockexpr != null)
+ {
+ var childResultPropBinding = Expression.Bind(childResultProp, childRuleResultsblockexpr);
+ memberInit = Expression.MemberInit(ctor, new[] { rulePropBinding, isSuccessPropBinding, childResultPropBinding, inputBinding, exceptionBinding });
+ }
+ else
+ {
+ memberInit = Expression.MemberInit(ctor, new[] { rulePropBinding, isSuccessPropBinding, inputBinding, exceptionBinding });
+ }
+
+ return memberInit;
+ }
+
+ ///
+ /// To the result tree error messages
+ ///
+ /// ruleResultTree
+ /// ruleResultMessage
+ internal static void ToResultTreeMessages(RuleResultTree ruleResultTree, ref RuleResultMessage ruleResultMessage)
+ {
+ if (ruleResultTree.ChildResults != null)
+ {
+ GetChildRuleMessages(ruleResultTree.ChildResults, ref ruleResultMessage);
+ }
+ else
+ {
+ if (ruleResultTree.IsSuccess)
+ {
+ string errMsg = ruleResultTree.Rule.ErrorMessage;
+ errMsg = string.IsNullOrEmpty(errMsg) ? $"Error message does not configured for {ruleResultTree.Rule.RuleName}" : errMsg;
+
+ if (ruleResultTree.Rule.ErrorType == ErrorType.Error && !ruleResultMessage.ErrorMessages.Contains(errMsg))
+ {
+ ruleResultMessage.ErrorMessages.Add(errMsg);
+ }
+ else if (ruleResultTree.Rule.ErrorType == ErrorType.Warning && !ruleResultMessage.WarningMessages.Contains(errMsg))
+ {
+ ruleResultMessage.WarningMessages.Add(errMsg);
+ }
+ }
+ }
+ }
+
+ ///
+ /// To get the child error message recersivly
+ ///
+ /// childResultTree
+ /// ruleResultMessage
+ private static void GetChildRuleMessages(IEnumerable childResultTree, ref RuleResultMessage ruleResultMessage)
+ {
+ foreach (var item in childResultTree)
+ {
+ ToResultTreeMessages(item, ref ruleResultMessage);
+ }
+ }
+ }
+}
diff --git a/src/RulesEngine/HelperFunctions/Utils.cs b/src/RulesEngine/RulesEngine/HelperFunctions/Utils.cs
similarity index 100%
rename from src/RulesEngine/HelperFunctions/Utils.cs
rename to src/RulesEngine/RulesEngine/HelperFunctions/Utils.cs
diff --git a/src/RulesEngine/Interfaces/IRulesEngine.cs b/src/RulesEngine/RulesEngine/Interfaces/IRulesEngine.cs
similarity index 100%
rename from src/RulesEngine/Interfaces/IRulesEngine.cs
rename to src/RulesEngine/RulesEngine/Interfaces/IRulesEngine.cs
diff --git a/src/RulesEngine/Models/CompiledParam.cs b/src/RulesEngine/RulesEngine/Models/CompiledParam.cs
similarity index 92%
rename from src/RulesEngine/Models/CompiledParam.cs
rename to src/RulesEngine/RulesEngine/Models/CompiledParam.cs
index dc55578..c05b968 100644
--- a/src/RulesEngine/Models/CompiledParam.cs
+++ b/src/RulesEngine/RulesEngine/Models/CompiledParam.cs
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
-using System.Diagnostics.CodeAnalysis;
using System.Text;
namespace RulesEngine.Models
@@ -8,7 +7,6 @@ namespace RulesEngine.Models
///
/// CompiledParam class.
///
- [ExcludeFromCodeCoverage]
internal class CompiledParam
{
///
diff --git a/src/RulesEngine/RulesEngine/Models/CompiledRule.cs b/src/RulesEngine/RulesEngine/Models/CompiledRule.cs
new file mode 100644
index 0000000..f1d7959
--- /dev/null
+++ b/src/RulesEngine/RulesEngine/Models/CompiledRule.cs
@@ -0,0 +1,31 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+
+namespace RulesEngine.Models
+{
+ [ExcludeFromCodeCoverage]
+ internal class CompiledRule
+ {
+ ///
+ /// Gets or sets the compiled rules.
+ ///
+ ///
+ /// The compiled rules.
+ ///
+ internal Delegate Rule { get; set; }
+
+
+ ///
+ /// Gets or sets the rule parameters.
+ ///
+ ///
+ /// The rule parameters.
+ ///
+ internal CompiledRuleParam CompiledParameters { get; set; }
+ }
+
+}
diff --git a/src/RulesEngine/RulesEngine/Models/CompiledRuleParam.cs b/src/RulesEngine/RulesEngine/Models/CompiledRuleParam.cs
new file mode 100644
index 0000000..cecd2d5
--- /dev/null
+++ b/src/RulesEngine/RulesEngine/Models/CompiledRuleParam.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace RulesEngine.Models
+{
+ /// Class CompiledRule.
+ internal class CompiledRuleParam
+ {
+ ///
+ /// Gets or sets the compiled rules.
+ ///
+ ///
+ /// The compiled rules.
+ ///
+ internal string Name { get; set; }
+
+ /// Gets or sets the rule parameters.
+ /// The rule parameters.
+ internal IEnumerable CompiledParameters { get; set; }
+
+ ///
+ /// Gets or sets the rule parameters.
+ ///
+ ///
+ /// The rule parameters.
+ ///
+ internal IEnumerable RuleParameters { get; set; }
+ }
+}
diff --git a/src/RulesEngine/Models/LocalParam.cs b/src/RulesEngine/RulesEngine/Models/LocalParam.cs
similarity index 81%
rename from src/RulesEngine/Models/LocalParam.cs
rename to src/RulesEngine/RulesEngine/Models/LocalParam.cs
index 302472b..754e0be 100644
--- a/src/RulesEngine/Models/LocalParam.cs
+++ b/src/RulesEngine/RulesEngine/Models/LocalParam.cs
@@ -1,11 +1,9 @@
using Newtonsoft.Json;
-using System.Diagnostics.CodeAnalysis;
namespace RulesEngine.Models
{
- /// Class LocalParam.
- ///
- [ExcludeFromCodeCoverage]
+ /// Class Param.
+ /// Implements the
public class LocalParam
{
diff --git a/src/RulesEngine/Models/ReSettings.cs b/src/RulesEngine/RulesEngine/Models/ReSettings.cs
similarity index 100%
rename from src/RulesEngine/Models/ReSettings.cs
rename to src/RulesEngine/RulesEngine/Models/ReSettings.cs
diff --git a/src/RulesEngine/Models/Rule.cs b/src/RulesEngine/RulesEngine/Models/Rule.cs
similarity index 99%
rename from src/RulesEngine/Models/Rule.cs
rename to src/RulesEngine/RulesEngine/Models/Rule.cs
index 10423ec..f0178fa 100644
--- a/src/RulesEngine/Models/Rule.cs
+++ b/src/RulesEngine/RulesEngine/Models/Rule.cs
@@ -85,6 +85,7 @@ namespace RulesEngine.Models
///
public string Expression { get; set; }
+
///
/// Gets or sets the success event.
///
@@ -94,4 +95,5 @@ namespace RulesEngine.Models
public string SuccessEvent { get; set; }
}
+
}
diff --git a/src/RulesEngine/Models/RuleErrorType.cs b/src/RulesEngine/RulesEngine/Models/RuleErrorType.cs
similarity index 100%
rename from src/RulesEngine/Models/RuleErrorType.cs
rename to src/RulesEngine/RulesEngine/Models/RuleErrorType.cs
diff --git a/src/RulesEngine/Models/RuleExpressionType.cs b/src/RulesEngine/RulesEngine/Models/RuleExpressionType.cs
similarity index 100%
rename from src/RulesEngine/Models/RuleExpressionType.cs
rename to src/RulesEngine/RulesEngine/Models/RuleExpressionType.cs
diff --git a/src/RulesEngine/Models/RuleInput.cs b/src/RulesEngine/RulesEngine/Models/RuleInput.cs
similarity index 100%
rename from src/RulesEngine/Models/RuleInput.cs
rename to src/RulesEngine/RulesEngine/Models/RuleInput.cs
diff --git a/src/RulesEngine/Models/RuleParameter.cs b/src/RulesEngine/RulesEngine/Models/RuleParameter.cs
similarity index 100%
rename from src/RulesEngine/Models/RuleParameter.cs
rename to src/RulesEngine/RulesEngine/Models/RuleParameter.cs
diff --git a/src/RulesEngine/Models/RuleResultTree.cs b/src/RulesEngine/RulesEngine/Models/RuleResultTree.cs
similarity index 100%
rename from src/RulesEngine/Models/RuleResultTree.cs
rename to src/RulesEngine/RulesEngine/Models/RuleResultTree.cs
diff --git a/src/RulesEngine/Models/WorkflowRules.cs b/src/RulesEngine/RulesEngine/Models/WorkflowRules.cs
similarity index 100%
rename from src/RulesEngine/Models/WorkflowRules.cs
rename to src/RulesEngine/RulesEngine/Models/WorkflowRules.cs
diff --git a/src/RulesEngine/RulesEngine/ParamCache.cs b/src/RulesEngine/RulesEngine/ParamCache.cs
new file mode 100644
index 0000000..84c7e97
--- /dev/null
+++ b/src/RulesEngine/RulesEngine/ParamCache.cs
@@ -0,0 +1,86 @@
+using RulesEngine.Models;
+using System;
+using System.Collections.Concurrent;
+using System.Linq;
+
+namespace RulesEngine
+{
+ /// Maintains the cache of evaludated param.
+ internal class ParamCache where T : class
+ {
+ ///
+ /// The compile rules
+ ///
+ private readonly ConcurrentDictionary _evaluatedParams = new ConcurrentDictionary();
+
+ ///
+ ///
+ /// Determines whether the specified parameter key name contains parameters.
+ ///
+ ///
+ /// Name of the parameter key.
+ ///
+ /// true if the specified parameter key name contains parameters; otherwise, false.
+ public bool ContainsParams(string paramKeyName)
+ {
+ return _evaluatedParams.ContainsKey(paramKeyName);
+ }
+
+ /// Adds the or update evaluated parameter.
+ /// Name of the parameter key.
+ /// The rule parameters.
+ public void AddOrUpdateParams(string paramKeyName, T ruleParameters)
+ {
+ _evaluatedParams.AddOrUpdate(paramKeyName, ruleParameters, (k, v) => v);
+ }
+
+ /// Clears this instance.
+ public void Clear()
+ {
+ _evaluatedParams.Clear();
+ }
+
+ /// Gets the evaluated parameters.
+ /// Name of the parameter key.
+ /// Delegate[].
+ public T GetParams(string paramKeyName)
+ {
+ return _evaluatedParams[paramKeyName];
+ }
+
+ /// Gets the evaluated parameters cache key.
+ /// Name of the workflow.
+ /// The rule.
+ /// Cache key.
+ public string GetCompiledParamsCacheKey(string workflowName, Rule rule)
+ {
+ if (rule == null)
+ {
+ return string.Empty;
+ }
+ else
+ {
+ if (rule?.LocalParams == null)
+ {
+ return $"Compiled_{workflowName}_{rule.RuleName}";
+ }
+
+ return $"Compiled_{workflowName}_{rule.RuleName}_{string.Join("_", rule?.LocalParams.Select(r => r?.Name))}";
+ }
+ }
+
+ /// Removes the specified workflow name.
+ /// Name of the workflow.
+ public void RemoveCompiledParams(string paramKeyName)
+ {
+ if (_evaluatedParams.TryRemove(paramKeyName, out T ruleParameters))
+ {
+ var compiledKeysToRemove = _evaluatedParams.Keys.Where(key => key.StartsWith(paramKeyName));
+ foreach (var key in compiledKeysToRemove)
+ {
+ _evaluatedParams.TryRemove(key, out T val);
+ }
+ }
+ }
+ }
+}
diff --git a/src/RulesEngine/ParamCompiler.cs b/src/RulesEngine/RulesEngine/ParamCompiler.cs
similarity index 95%
rename from src/RulesEngine/ParamCompiler.cs
rename to src/RulesEngine/RulesEngine/ParamCompiler.cs
index 09f1462..03e7689 100644
--- a/src/RulesEngine/ParamCompiler.cs
+++ b/src/RulesEngine/RulesEngine/ParamCompiler.cs
@@ -70,8 +70,8 @@ namespace RulesEngine
var expression = Expression.Lambda(ruleParamExpression, lambdaParameterExps);
var compiledParam = expression.Compile();
compiledParameters.Add(new CompiledParam { Name = param.Name, Value = compiledParam, Parameters = evaluatedParameters });
- var evaluatedParam = this.EvaluateCompiledParam(param.Name, compiledParam, ruleParams.Select(c => c.Value).ToArray());
- ruleParams = ruleParams.Append(evaluatedParam);
+ var evaluatedParam = this.EvaluateCompiledParam(param.Name, compiledParam, ruleParams);
+ ruleParams = ruleParams.Concat(new List { evaluatedParam });
evaluatedParameters.Add(evaluatedParam);
}
@@ -86,8 +86,9 @@ namespace RulesEngine
/// The compiled parameter.
/// The rule parameters.
/// RuleParameter.
- public RuleParameter EvaluateCompiledParam(string paramName, Delegate compiledParam, IEnumerable