/// <summary> /// Compiles the and evaluate parameter expression. /// </summary> /// <param name="rule">The rule.</param> /// <param name="ruleParams">The rule parameters.</param> /// <returns> /// IEnumerable<RuleParameter>. /// </returns> public CompiledRuleParam CompileParamsExpression(Rule rule, IEnumerable <RuleParameter> ruleParams) { CompiledRuleParam compiledRuleParam = null; if (rule.LocalParams != null) { var compiledParameters = new List <CompiledParam>(); var evaluatedParameters = new List <RuleParameter>(); foreach (var param in rule.LocalParams) { IEnumerable <ParameterExpression> typeParameterExpressions = GetParameterExpression(ruleParams.ToArray()).ToList(); // calling ToList to avoid multiple calls this the method for nested rule scenario. ParameterExpression ruleInputExp = Expression.Parameter(typeof(RuleInput), nameof(RuleInput)); var ruleParamExpression = GetExpressionForRuleParam(param, typeParameterExpressions, ruleInputExp); var lambdaParameterExps = new List <ParameterExpression>(typeParameterExpressions) { ruleInputExp }; var expression = Expression.Lambda(ruleParamExpression, lambdaParameterExps); var compiledParam = expression.Compile(); compiledParameters.Add(new CompiledParam { Name = param.Name, Value = compiledParam, Parameters = evaluatedParameters }); var evaluatedParam = this.EvaluateCompiledParam(param.Name, compiledParam, ruleParams.Select(c => c.Value).ToArray()); ruleParams = ruleParams.Append(evaluatedParam); evaluatedParameters.Add(evaluatedParam); } compiledRuleParam = new CompiledRuleParam { Name = rule.RuleName, CompiledParameters = compiledParameters, RuleParameters = evaluatedParameters }; } return(compiledRuleParam); }
/// <summary> /// This will compile the rules and store them to dictionary /// </summary> /// <param name="workflowName">workflow name</param> /// <param name="ruleParams">The rule parameters.</param> /// <returns> /// bool result /// </returns> private bool RegisterRule(string workflowName, params RuleParameter[] ruleParams) { string compileRulesKey = _rulesCache.GetRulesCacheKey(workflowName); if (_rulesCache.ContainsCompiledRules(compileRulesKey)) { return(true); } var workflowRules = _rulesCache.GetWorkFlowRules(workflowName); if (workflowRules != null) { var lstFunc = new List <RuleFunc <RuleResultTree> >(); var ruleCompiler = new RuleCompiler(new RuleExpressionBuilderFactory(_reSettings), _logger); foreach (var rule in _rulesCache.GetRules(workflowName)) { var compiledParamsKey = GetCompiledParamsCacheKey(workflowName, rule); CompiledRuleParam compiledRuleParam = _compiledParamsCache.GetOrCreate(compiledParamsKey, (entry) => ruleParamCompiler.CompileParamsExpression(rule, ruleParams)); var updatedRuleParams = compiledRuleParam != null?ruleParams?.Concat(compiledRuleParam?.RuleParameters) : ruleParams; var compiledRule = ruleCompiler.CompileRule(rule, updatedRuleParams?.ToArray()); RuleFunc <RuleResultTree> updatedRule = (object[] paramList) => { var inputs = paramList.AsEnumerable(); IEnumerable <CompiledParam> localParams = compiledRuleParam?.CompiledParameters ?? new List <CompiledParam>(); foreach (var localParam in localParams) { var evaluatedLocalParam = ruleParamCompiler.EvaluateCompiledParam(localParam.Name, localParam.Value, inputs); inputs = inputs.Append(evaluatedLocalParam.Value); } var result = compiledRule(inputs.ToArray()); result.RuleEvaluatedParams = compiledRuleParam?.RuleParameters; return(result); }; lstFunc.Add(updatedRule); } _rulesCache.AddOrUpdateCompiledRule(compileRulesKey, lstFunc); _logger.LogTrace($"Rules has been compiled for the {workflowName} workflow and added to dictionary"); return(true); } else { return(false); } }