.net RulesEngine 规则引擎使用

唐弘厚
2023-12-01

Microsoft RulesEngine 规则引擎使用

贴GitHub地址:

github地址: microsoft/RulesEngine

装入项目

这里我由于项目中是framework的,所以我装的framework版本,直接在项目中,打开nuget管理,
搜索RulesEngine安装即可。

实际使用 simple example:

先配置Rule Json字符串,比如我这里声明一个test,里面有两个规则,test1,test4,表达式条件分别为:
test1:传入的值中,CODE要为test,同时NAME为test1,2,3的,使用这个规则;
test2:传入的值中,CODE要为test,同时NAME为test4,5的,使用这个规则;

[
    {
        "WorkflowName": "test",
        "Rules": [
            {
                "RuleName": "test1",
                "SuccessEvent": "test1匹配成功!",
                "ErrorMessage": "One or more adjust rules failed.",
                "ErrorType": "Error",
                "RuleExpressionType": "LambdaExpression",
                "Expression": "input1.CODE == \"test\" AND ( input1.NAME == \"test1\" OR input1.NAME == \"test2\" OR input2.NAME == \"test3\" )"
            },
            {
                "RuleName": "test4",
                "SuccessEvent": "test4匹配成功",
                "ErrorMessage": "One or more adjust rules failed.",
                "ErrorType": "Error",
                "RuleExpressionType": "LambdaExpression",
                "Expression": "input1.CODE == \"test\" AND ( input1.NAME == \"test4\" OR input1.NAME == \"test5\" )"
            }
        ]
    }
]

将这个json值存入数据库表Rules中,id为1,Rule为值;

后端代码,:

           var db = DBHelper.DB2;  //DB访问
            var rules = db.Queryable<Rules>().Where(x => x.ID == 1).First();  //找到id为1的rule json
            var bre = new RulesEngine.RulesEngine(JsonConvert.DeserializeObject<List<WorkflowRules>>(rules.Rule).ToArray(), null); //声明一个RulesEngine

            var testInfo = "{\"CODE\": \"test\",\"NAME\": \"test4\"}"; //声明传入参数变量,实际使用中的数据

            string result = ""; //结果
            
            List<RuleResultTree> resultList = bre.ExecuteRule("test", JsonConvert.DeserializeObject<ExpandoObject>(testInfo, new ExpandoObjectConverter())); //执行规则,这里传入实际值,且第一个参数"test"是json中的WorkflowName

            resultList.OnSuccess((eventValue) =>
            {
                result = $"{eventValue}";
            });

            resultList.OnFail(() =>
            {
                result = "False!";
            });

            Console.WriteLine("匹配结果:" + result);

这样就可以运行起来了。

复杂点的使用:

实际使用过程中,肯定不会像上面这样这么简单,不过上面已经可以覆盖多数范围了,我们实际使用中,数据一般都是Entitiy,那么这时候,RuleEngine支持localParams
使用方式基本类似:
声明rule json:

[
    {
        "WorkflowName": "test",
        "Rules": [
            {
                "RuleName": "test1",
                "SuccessEvent": "true",
                "ErrorMessage": "One or more adjust rules failed.",
                "ErrorType": "Error",
                "localParams": [
                {
                    "Name": "model1",
                    "Expression": "input1model.Where(CODE.Equals(\"test\", StringComparison.InvariantCultureIgnoreCase))"
                }
                ],
                "RuleExpressionType": "LambdaExpression",
                "Expression": "model1.Any() AND ( inputmodel2.CODE == \"11\" OR inputmodel2.CODE == \"22\" OR inputmodel2.CODE == \"33\" )"
            }
        ]
    }
]

如我上面的rule,若是要使用Where条件,这里需要传入Entitiy,而不能传入json字符串,这个传入json字符串虽然也有code字段,但是不认。
后端代码:

						var db = DBHelper.DB2;
            var rules = db.Queryable<Rules>().Where(x => x.ID == 3).First();
            var mpiylist = db.Queryable<MD_PRODUCT_INFO_Y>().ToList();
            var macList = db.Queryable<MD_ALL_CHAPTER_INFO>().ToList();
            var bre = new RulesEngine.RulesEngine(JsonConvert.DeserializeObject<List<WorkflowRules>>(rules.Rule).ToArray(), null);

            foreach (var item in mpiylist)
            {
                var ruleParams = new List<RuleParameter>();
                ruleParams.Add(new RuleParameter("input1model", Utils.GetTypedObject(macList))); \\inputmodel1 这个要跟rule里对应起来,名字可以自定义
                ruleParams.Add(new RuleParameter("inputmodel2", Utils.GetTypedObject(item))); \\这里要这样传入,不能先将entity json化后再传入,这样rule中的Where条件不起作用,

                List<RuleResultTree> resultList = bre.ExecuteRule("test", ruleParams?.ToArray());
                string result = "False";
                resultList.OnSuccess((eventValue) =>
                {
                    result = $"{eventValue}";
                });
                resultList.OnFail(() =>
                {
                    result = "False!";
                });
                Console.WriteLine("匹配结果:" + result);

            }

基本使用方式就是这样,目前的已经可以满足我的需求了,未再深入。

 类似资料: