C# RulesEngine 规则引擎:从入门到看懵( 四 )

定义规则计算,每个规则计算的是自己的折扣:
[{ "WorkflowName": "Test", "GlobalParams": [{"Name": "value","Expression": "discount.Value" }], "Rules": [{"RuleName": "CheckAge","Expression": "buyer.age < 18","Actions": {"OnSuccess": {"Name": "OutputExpression","Context": {"Expression": "value * 0.9"}}}},{"RuleName": "CheckVIP","Expression": "vip.IsVIP == true","Actions": {"OnSuccess": {"Name": "OutputExpression","Context": {"Expression": "value * 0.9"}}}} ]}]

C# RulesEngine 规则引擎:从入门到看懵

文章插图
完整代码:
static async Task Main(){// 定义var rulesStr =... ... // JSONvar workflows = JsonConvert.DeserializeObject<List<Workflow>>(rulesStr)!;var bre = new RulesEngine.RulesEngine(workflows.ToArray());var rp1 = new RuleParameter("buyer", new Buyer{Id = 666,Age = 16,});var rp2 = new RuleParameter("vip", new VIP{Id = 666,IsVIP = true});var rp3 = new RuleParameter("discount", new Discount{Value = https://www.huyubaike.com/biancheng/1.0});List resultList = await bre.ExecuteAllRulesAsync("Test", rp1, rp2, rp3);var discount = 1.0;foreach (var item in resultList){if (item.ActionResult != null && item.ActionResult.Output != null){Console.WriteLine($"{item.Rule.RuleName} 折扣优惠:{item.ActionResult.Output}");discount = discount * (double)item.ActionResult.Output;}}Console.WriteLine($"最终折扣:{discount}");}笔者这里的示例是,每个规则只计算自己的折扣,也就是每个 Rule 都是独立的,下一个 Rule 不会在上一个 Rule 结果上计算 。
< 18 : 0.9VIP: 0.9如果是折扣可以叠加,那么就是 0.9*0.9,最终可以拿到 0.81 的折扣 。
如果折扣不能叠加,只能选择最佳的优惠,那么就是 0.9
使用自定义函数自定义函数有两种静态函数和实例函数两种 , 我们可以在 Expression 中调用预先写好的函数 。
下面讲解如何在 Rule 中调用自定义的函数 。
静态函数自定义静态函数:
public static bool CheckAge(int age){return age >= 18;}注册类型:
ReSettings reSettings = new ReSettings{CustomTypes = new[] { typeof(Program) }};var bre = new RulesEngine.RulesEngine(Workflows: workflows.ToArray(), reSettings: reSettings);使用静态函数:
[{ "WorkflowName": "Test", "Rules": [{"RuleName": "CheckAge","Expression": "Program.CheckAge(buyer.Age) == true" }]}]完整代码:
static async Task Main(){// 定义var rulesStr = "[{\"WorkflowName\":\"Test\",\"Rules\":[{\"RuleName\":\"CheckAge\",\"Expression\":\"Program.CheckAge(buyer.Age) == true\"}]}]";var workflows = JsonConvert.DeserializeObject<List<Workflow>>(rulesStr)!;ReSettings reSettings = new ReSettings{CustomTypes = new[] { typeof(Program) }};var bre = new RulesEngine.RulesEngine(Workflows: workflows.ToArray(), reSettings: reSettings);List<RuleResultTree> resultList = await bre.ExecuteAllRulesAsync("Test", new Buyer{Age = 16});foreach (var item in resultList){Console.WriteLine("规则名称:{0},验证结果:{1}", item.Rule.RuleName, item.IsSuccess);}}public static bool CheckAge(int age){return age >= 18;}实例函数定义实例函数:
public bool CheckAge(int age){return age >= 18;}通过 RuleParameter 参数的方式,传递实例:
var rp1 = new RuleParameter("p", new Program());通过参数的名称调用函数:
[{ "WorkflowName": "Test", "Rules": [{"RuleName": "CheckAge","Expression": "p.CheckAge(buyer.Age) == true" }]}]完整代码:
static async Task Main(){// 定义var rulesStr = "[{\"WorkflowName\":\"Test\",\"Rules\":[{\"RuleName\":\"CheckAge\",\"Expression\":\"p.CheckAge(buyer.Age) == true\"}]}]";var workflows = JsonConvert.DeserializeObject<List<Workflow>>(rulesStr)!;var rp1 = new RuleParameter("p", new Program());var bre = new RulesEngine.RulesEngine(Workflows: workflows.ToArray());List<RuleResultTree> resultList = await bre.ExecuteAllRulesAsync("Test", new Buyer{Age = 16}, rp1);foreach (var item in resultList){Console.WriteLine("规则名称:{0},验证结果:{1}", item.Rule.RuleName, item.IsSuccess);}}public bool CheckAge(int age){return age >= 18;}自定义执行器自定义执行器就是 OnSuccessOnFailure 这部分的自定义执行代码,相比静态函数、实例函数 , 使用自定义执行器,可以获取 Rule 的一些数据 。
"Actions": {"OnSuccess": {"Name": "MyCustomAction","Context": {"customContextInput": "0.9"}}}自定义一个执行器,执行器需要继承 ActionBase
public class MyCustomAction : ActionBase{public override async ValueTask<object> Run(ActionContext context, RuleParameter[] ruleParameters){var customInput = context.GetContext<string>("customContextInput");return await ValueTask.FromResult(new object());}}

推荐阅读