microsoft / RulesEngine

A Json based Rules Engine with extensive Dynamic expression support
https://microsoft.github.io/RulesEngine/
MIT License
3.6k stars 543 forks source link

Error when the value of the name parameter of a RuleParameter is the same as the class name of the value parameter #540

Closed duguankui closed 10 months ago

duguankui commented 11 months ago
using Newtonsoft.Json;
using RulesEngine.Models;
using RulesEngineSample;

var rulesStr = @"[{
    ""WorkflowName"": ""Test"", 
    ""GlobalParams"": [{
        ""Name"": ""discount1"",
        ""Expression"": ""discount12.Value""
    }],
    ""Rules"": [{
            ""RuleName"": ""CheckAge"",
            ""Expression"": ""buyer.Age < 18"",
            ""Actions"": {
                ""OnSuccess"": {
                    ""Name"": ""OutputExpression"",
                    ""Context"": {
                        ""Expression"": ""discount1 * 0.9""
                    }
                }
            }
        },
        {
            ""RuleName"": ""CheckVIP"",
            ""Expression"": ""vipq.IsVIP == true"",
            ""Actions"": {
                ""OnSuccess"": {
                    ""Name"": ""OutputExpression"",
                    ""Context"": {
                        ""Expression"": ""discount1 * 0.9""
                    }
                }
            }
        }
    ]
}]";

var rp1 = new RuleParameter("buyer", new Buyer
{
    Id = 666,
    Age = 16
});

var rp2 = new RuleParameter("vipq", new VIP
{
    Id = 666,
    IsVIP = false
});

var rp3 = new RuleParameter("discount12", new Discount
{
    Value = 1.0
});

var workflows = JsonConvert.DeserializeObject<List<Workflow>>(rulesStr)!;
var bre = new RulesEngine.RulesEngine(workflows.ToArray());

List<RuleResultTree> 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}");

When the program runs to line 65, an error message appears in item.ExceptionMessage: "Exception while parsing expression buyer.Age < 18 - No property or field 'Age' exists in type 'Buyer' ". The reason is that the error occurs when a RuleParameter with the name buyer is defined in line 40 of the code and the Value class name of that RuleParameter is the same as buyer. Changing buyer to buy and changing buyer.Age to buy.Age in line 15 of the code worked.