microsoft / RulesEngine

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

Strange behavior with UseFastExpressionCompiler = true when local param contains plus operator #608

Open MinhNguyenDev opened 3 weeks ago

MinhNguyenDev commented 3 weeks ago

How to reproduce:

Create a local param that is the calculation of 3 other local params, when UseFastExpressionCompiler flag set to false, the rule can run successfully, but when UseFastExpressionCompiler = true, it has an exception and failed :

    `var reSettingsWithCustomTypes = new ReSettings {
        UseFastExpressionCompiler = true
    };
    var rule = new Rule {
        RuleName = "check local param with plus operator",
        Expression = "Total > 0",
        LocalParams = new List<ScopedParam>() {
            new() {
                Name = "Field1",
                Expression = "AppData.Details.Sum(l => l.Amount)"
            },
            new() {
                Name = "Field2",
                Expression = "AppData.Details.Sum(l => l.Amount)"
            },
            new() {
                Name = "Field3",
                Expression = "AppData.Details.Sum(l => l.Amount)"
            },
            new() { Name = "Total", Expression = "Field1 + Field2 + Field3" },
        }
    };

    var worflow = new Workflow {
        WorkflowName = "UseFastExpressionCompilerTest",
        Rules = new[] { rule }
    };

    var input = new AppData() {
        Details = new() { new() { Amount = 1 }, new() { Amount = 2 }, new() { Amount = 3 }, }
    };

    var appData = new RuleParameter("AppData", input);

    var re = new RulesEngine(new[] { worflow }, reSettingsWithCustomTypes);
    var result = await re.ExecuteAllRulesAsync("UseFastExpressionCompilerTest", new[] { appData });

    Assert.Equal(true, result[0].IsSuccess);
}

public class AppData
{
    public List<Detail> Details { get; set; } = new List<Detail>();
}

public class Detail
{
    public decimal? Amount { get; set; }
}`

The exception was "Object reference not set to an instance of an object." in RuleCompiler

asulwer commented 1 week ago

in my testing

worked - remove nullable from your decimal property worked - Expression = "AppData.Details.Sum(l => l.Amount.Value)" VALUE added