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


正常来看代码应该这样写:
if(Authenticated == true && Age > 18)但是如果年龄调为 16 岁呢?如果最近公司搞活动,不需要上传身份证就能购买商品呢?
当然定义变量存储到数据库也行,但是如果后面又新增了几个条件,那么我们就需要修改代码了,大佬说,这样不好,我们要 RulesEngine。
好的,那我们来研究一下这个东西 。
前面提到的 if(Authenticated == true && Age > 18),这么一个完整的验证过程,在 RulesEngine 称为 Workflow,每个 Workflow 下有多个 Rule 。
if(Authenticated == true && Age > 18) => WorkflowAuthenticated == true=> RuleAge > 18=> Rule在 RulesEngine中,有两种方法定义这些 Workflow 和 Rule,一种是使用代码,一种是 JSON,官方是推荐使用 JSON 的,因为 JSON 可以动态生成,可以实现真正的动态 。
下面我们来看看如何使用 JSON 和代码,分别定义if(Authenticated == true && Age > 18) 这个验证过程 。
JSON 定义:
[{"WorkflowName": "Test","Rules": [{"RuleName": "CheckAuthenticated","Expression": "Authenticated == true"},{"RuleName": "CheckAge","Expression": "Age >= 18"}]}]var rulesStr = "[{... ...}]" // JSONvar workflows = JsonConvert.DeserializeObject<List<Workflow>>(rulesStr);C# 代码:
var workflows = new List<Workflow>();List<Rule> rules = new List<Rule>();Workflow exampleWorkflow = new Workflow();exampleWorkflow.WorkflowName = "Test";exampleWorkflow.Rules = rules;workflows.Add(exampleWorkflow);Rule authRule = new Rule();authRule.RuleName = "CheckAuthenticated";authRule.Expression = "Authenticated == true";rules.Add(authRule);Rule ageRule = new Rule();ageRule.RuleName = "CheckAuthenticated";ageRule.Expression = "Authenticated == true";rules.Add(ageRule);两种方式都是一样的,每个 Workflow 下有多个 Rule,可以定义多个 Workflow 。
当前我们有两个地方要了解:
"RuleName": "CheckAuthenticated","Expression": "Authenticated == true"RuleName:规则名称;
Expression: 真实的代码,必须是符合 C# 语法的代码;
定义好 Workflow 和 Rule 后,我们需要生成规则引擎,直接 new RulesEngine.RulesEngine() 即可:
var bre = new RulesEngine.RulesEngine(workflows.ToArray());

生成引擎是需要一些时间的 。
生成引擎后,我们通过名称指定调用一个 Workflow,并获取每个 Rule 的验证结果:
List<RuleResultTree> resultList = await bre.ExecuteAllRulesAsync("Test", new Buyer{Id = 666,Age = 17,Authenticated = false});完整代码示例如下:
static async Task Main(){// 定义var rulesStr = ... ...// JSON// 生成 Workflow[ Rule[] ]var workflows = JsonConvert.DeserializeObject<List<Workflow>>(rulesStr)!;var bre = new RulesEngine.RulesEngine(workflows.ToArray());// 调用指定的 Workflow,并传递参数,获取每个 Rule 的处理结果List<RuleResultTree> resultList = await bre.ExecuteAllRulesAsync("Test", new Buyer{Id = 666,Age = 17,Authenticated = false});// 打印输出foreach (var item in resultList){Console.WriteLine("规则名称:{0},验证结果:{1}", item.Rule.RuleName, item.IsSuccess);}}
C# RulesEngine 规则引擎:从入门到看懵

文章插图
多参数如果商品需要 VIP 才能购买呢?
这里我们再定义一个模型类,表示一个用户是否为 VIP 。
public class VIP{public int Id { get; set; }public bool IsVIP { get; set; }}那么这个时候就需要处理两个模型类了,为了能够在 Rule 中使用所有的模型类,我们需要为每个模型类定义

经验总结扩展阅读