diff --git a/demo/DemoApp/Demos/Basic.cs b/demo/DemoApp/Demos/Basic.cs index d24f88de..593a7480 100644 --- a/demo/DemoApp/Demos/Basic.cs +++ b/demo/DemoApp/Demos/Basic.cs @@ -56,7 +56,7 @@ public async Task Run(CancellationToken ct = default) outcome = true; }); - resultList.OnFail(() => { + resultList.OnFail((eventName) => { outcome = false; }); diff --git a/demo/DemoApp/Demos/BasicWithCustomTypes.cs b/demo/DemoApp/Demos/BasicWithCustomTypes.cs new file mode 100644 index 00000000..a8bc4354 --- /dev/null +++ b/demo/DemoApp/Demos/BasicWithCustomTypes.cs @@ -0,0 +1,73 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using RulesEngine.Models; +using System; +using System.Collections.Generic; +using System.Dynamic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using static RulesEngine.Extensions.ListofRuleResultTreeExtension; + +namespace DemoApp.Demos +{ + public class BasicWithCustomTypes + { + internal 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); + } + } + public async Task Run(CancellationToken ct = default) + { + Console.WriteLine($"Running {nameof(BasicWithCustomTypes)}...."); + var workflows = new List(); + var workflow = new Workflow(); + workflow.WorkflowName = "Test Workflow Rule 1"; + + var rules = new List { + new Rule() { + RuleName = "Test Rule", + SuccessMessage = "doSomething ran successfully", + ErrorMessage = "doSomething failed", + Expression = "Utils.CheckContains(string1, \"bye,seeya,hello\") == true", + RuleExpressionType = RuleExpressionType.LambdaExpression + } + }; + + workflow.Rules = rules; + workflows.Add(workflow); + + var reSettings = new ReSettings { + CustomTypes = [ typeof(Utils) ] + }; + + var bre = new RulesEngine.RulesEngine(workflows.ToArray(), reSettings); + + var string1 = new RuleParameter("string1", "hello"); + + var ruleResultTree = await bre.ExecuteAllRulesAsync("Test Workflow Rule 1", [string1], ct); + ruleResultTree.OnSuccess((eventName) => { + Console.WriteLine($"Result '{eventName}' is as expected."); + }); + ruleResultTree.OnFail((eventName) => { + Console.WriteLine($"Test outcome: false"); + }); + + var actionRuleResult = await bre.ExecuteActionWorkflowAsync("Test Workflow Rule 1", "Test Rule", [string1], ct); + actionRuleResult.Results.OnSuccess((eventName) => { + Console.WriteLine($"Result '{eventName}' is as expected."); + }); + actionRuleResult.Results.OnFail((eventName) => { + Console.WriteLine($"Test outcome: false"); + }); + } + } +} diff --git a/demo/DemoApp/Demos/EF.cs b/demo/DemoApp/Demos/EF.cs index 28a9fbd4..7261ad0c 100644 --- a/demo/DemoApp/Demos/EF.cs +++ b/demo/DemoApp/Demos/EF.cs @@ -70,7 +70,7 @@ public async Task Run(CancellationToken ct = default) discountOffered = $"Discount offered is {eventName} % over MRP."; }); - resultList.OnFail(() => { + resultList.OnFail((eventName) => { discountOffered = "The user is not eligible for any discount."; }); diff --git a/demo/DemoApp/Demos/JSON.cs b/demo/DemoApp/Demos/JSON.cs index a6cd5820..583e07c0 100644 --- a/demo/DemoApp/Demos/JSON.cs +++ b/demo/DemoApp/Demos/JSON.cs @@ -53,7 +53,7 @@ public async Task Run(CancellationToken ct = default) discountOffered = $"Discount offered is {eventName} % over MRP."; }); - resultList.OnFail(() => { + resultList.OnFail((eventName) => { discountOffered = "The user is not eligible for any discount."; }); diff --git a/demo/DemoApp/Demos/NestedInput.cs b/demo/DemoApp/Demos/NestedInput.cs index 2e99bc3d..fe649d5e 100644 --- a/demo/DemoApp/Demos/NestedInput.cs +++ b/demo/DemoApp/Demos/NestedInput.cs @@ -59,7 +59,7 @@ public async Task Run(CancellationToken ct = default) resultList.OnSuccess((eventName) => { Console.WriteLine($"{workflow.WorkflowName} evaluation resulted in success - {eventName}"); - }).OnFail(() => { + }).OnFail((eventName) => { Console.WriteLine($"{workflow.WorkflowName} evaluation resulted in failure"); }); } diff --git a/demo/DemoApp/Program.cs b/demo/DemoApp/Program.cs index d744373a..959222cd 100644 --- a/demo/DemoApp/Program.cs +++ b/demo/DemoApp/Program.cs @@ -19,6 +19,7 @@ public static async Task Main(string[] args) //cts.CancelAfter(TimeSpan.FromMilliseconds(94)); await new Demos.Basic().Run(cts.Token); + await new Demos.BasicWithCustomTypes().Run(cts.Token); await new Demos.JSON().Run(cts.Token); await new Demos.NestedInput().Run(cts.Token); await new Demos.EF().Run(cts.Token); diff --git a/src/RulesEngine/Extensions/ListofRuleResultTreeExtension.cs b/src/RulesEngine/Extensions/ListofRuleResultTreeExtension.cs index fc571ce8..b01db3b8 100644 --- a/src/RulesEngine/Extensions/ListofRuleResultTreeExtension.cs +++ b/src/RulesEngine/Extensions/ListofRuleResultTreeExtension.cs @@ -11,7 +11,7 @@ namespace RulesEngine.Extensions public static class ListofRuleResultTreeExtension { public delegate void OnSuccessFunc(string eventName); - public delegate void OnFailureFunc(); + public delegate void OnFailureFunc(string eventName); /// @@ -40,9 +40,13 @@ public static List OnSuccess(this List ruleResul /// public static List OnFail(this List ruleResultTrees, OnFailureFunc onFailureFunc) { - bool allFailure = ruleResultTrees.All(ruleResult => ruleResult.IsSuccess == false); - if (allFailure) - onFailureFunc(); + var allFailure = ruleResultTrees.FirstOrDefault(ruleResult => ruleResult.IsSuccess == false); + if (allFailure != null) + { + var eventName = allFailure.Rule.ErrorMessage ?? allFailure.Rule.RuleName; + onFailureFunc(eventName); + } + return ruleResultTrees; } } diff --git a/test/RulesEngine.UnitTest/ListofRuleResultTreeExtensionTest.cs b/test/RulesEngine.UnitTest/ListofRuleResultTreeExtensionTest.cs index f0184cf9..b2d97d62 100644 --- a/test/RulesEngine.UnitTest/ListofRuleResultTreeExtensionTest.cs +++ b/test/RulesEngine.UnitTest/ListofRuleResultTreeExtensionTest.cs @@ -164,7 +164,7 @@ public void OnFailWithSuccessTest() var successEventName = true; - rulesResultTree.OnFail(() => { + rulesResultTree.OnFail((eventName) => { successEventName = false; }); @@ -203,7 +203,7 @@ public void OnFailWithoutSuccessTest() var successEventName = true; - rulesResultTree.OnFail(() => { + rulesResultTree.OnFail((eventName) => { successEventName = false; });