From 10080c961b47f0bb7ab733669a646f70292a1a05 Mon Sep 17 00:00:00 2001 From: Jeremy Oursler Date: Mon, 28 Sep 2020 15:56:26 -0500 Subject: [PATCH 1/2] Fixes #26 Add useTryCatchForNulls defaulting to true to all public methods using GetExpressionForRule Remove default value from private and protected methods to ensure useTryCatch is always set for BuildExpr --- MicroRuleEngine/MRE.cs | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/MicroRuleEngine/MRE.cs b/MicroRuleEngine/MRE.cs index 8117313..2f898d2 100644 --- a/MicroRuleEngine/MRE.cs +++ b/MicroRuleEngine/MRE.cs @@ -42,10 +42,10 @@ public class MRE private static readonly Lazy _miDecimalTryParse = new Lazy(() => typeof(Decimal).GetMethod("TryParse", new Type[] { typeof(string), Type.GetType("System.Decimal&") })); - public Func CompileRule(Rule r) + public Func CompileRule(Rule r, bool useTryCatchForNulls = true) { var paramUser = Expression.Parameter(typeof(T)); - Expression expr = GetExpressionForRule(typeof(T), r, paramUser); + Expression expr = GetExpressionForRule(typeof(T), r, paramUser, useTryCatchForNulls); return Expression.Lambda>(expr, paramUser).Compile(); } @@ -61,10 +61,10 @@ public static Func ToFunc(Rule r, bool useTryCatchForNulls = true) { return ToExpression(r, useTryCatchForNulls).Compile(); } - public static Expression> ToExpression(Type type, Rule r) + public static Expression> ToExpression(Type type, Rule r, bool useTryCatchForNulls = true) { var paramUser = Expression.Parameter(typeof(object)); - Expression expr = GetExpressionForRule(type, r, paramUser); + Expression expr = GetExpressionForRule(type, r, paramUser, useTryCatchForNulls); return Expression.Lambda>(expr, paramUser); } @@ -74,30 +74,30 @@ public static Func ToFunc(Type type, Rule r) return ToExpression(type, r).Compile(); } - public Func CompileRule(Type type, Rule r) + public Func CompileRule(Type type, Rule r, bool useTryCatchForNulls = true) { var paramUser = Expression.Parameter(typeof(object)); - Expression expr = GetExpressionForRule(type, r, paramUser); + Expression expr = GetExpressionForRule(type, r, paramUser, useTryCatchForNulls); return Expression.Lambda>(expr, paramUser).Compile(); } - public Func CompileRules(IEnumerable rules) + public Func CompileRules(IEnumerable rules, bool useTryCatchForNulls = true) { var paramUser = Expression.Parameter(typeof(T)); - var expr = BuildNestedExpression(typeof(T), rules, paramUser, ExpressionType.And); + var expr = BuildNestedExpression(typeof(T), rules, paramUser, ExpressionType.And, useTryCatchForNulls); return Expression.Lambda>(expr, paramUser).Compile(); } - public Func CompileRules(Type type, IEnumerable rules) + public Func CompileRules(Type type, IEnumerable rules, bool useTryCatchForNulls = true) { var paramUser = Expression.Parameter(type); - var expr = BuildNestedExpression(type, rules, paramUser, ExpressionType.And); + var expr = BuildNestedExpression(type, rules, paramUser, ExpressionType.And, useTryCatchForNulls); return Expression.Lambda>(expr, paramUser).Compile(); } // Build() in some forks - protected static Expression GetExpressionForRule(Type type, Rule rule, ParameterExpression parameterExpression, bool useTryCatchForNulls = true) + protected static Expression GetExpressionForRule(Type type, Rule rule, ParameterExpression parameterExpression, bool useTryCatchForNulls) { ExpressionType nestedOperator; if (ExpressionType.TryParse(rule.Operator, out nestedOperator) && @@ -201,9 +201,9 @@ private static Expression GetProperty(Expression param, string propname) } private static Expression BuildEnumerableOperatorExpression(Type type, Rule rule, - ParameterExpression parameterExpression) + ParameterExpression parameterExpression, bool useTryCatchForNulls = true) { - var collectionPropertyExpression = BuildExpr(type, rule, parameterExpression); + var collectionPropertyExpression = BuildExpr(type, rule, parameterExpression, useTryCatchForNulls); var itemType = GetCollectionItemType(collectionPropertyExpression.Type); var expressionParameter = Expression.Parameter(itemType); @@ -211,7 +211,7 @@ private static Expression BuildEnumerableOperatorExpression(Type type, Rule rule var genericFunc = typeof(Func<,>).MakeGenericType(itemType, typeof(bool)); - var innerExp = BuildNestedExpression(itemType, rule.Rules, expressionParameter, ExpressionType.And); + var innerExp = BuildNestedExpression(itemType, rule.Rules, expressionParameter, ExpressionType.And, useTryCatchForNulls); var predicate = Expression.Lambda(genericFunc, innerExp, expressionParameter); var body = Expression.Call(typeof(Enumerable), rule.Operator, new[] { itemType }, @@ -239,7 +239,7 @@ where string.Equals(oprator, tup.Item1, StringComparison.CurrentCultureIgnoreCas select tup.Item2.Value).FirstOrDefault(); } - private static Expression BuildExpr(Type type, Rule rule, Expression param, bool useTryCatch = true) + private static Expression BuildExpr(Type type, Rule rule, Expression param, bool useTryCatch) { Expression propExpression; Type propType; @@ -343,7 +343,7 @@ private static Expression BuildExpr(Type type, Rule rule, Expression param, bool ? Expression.Call(enumrOperation.MakeGenericMethod(elementType), propExpression, Expression.Lambda( - BuildNestedExpression(elementType, rule.Rules, lambdaParam, ExpressionType.AndAlso), + BuildNestedExpression(elementType, rule.Rules, lambdaParam, ExpressionType.AndAlso, useTryCatch), lambdaParam) From adbefdae2ff8e3e28fd27bda4893aa5f3a574e63 Mon Sep 17 00:00:00 2001 From: Jeremy Oursler Date: Mon, 28 Sep 2020 16:34:02 -0500 Subject: [PATCH 2/2] Move to overloads instead of optional parameters. --- MicroRuleEngine/MRE.cs | 78 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 69 insertions(+), 9 deletions(-) diff --git a/MicroRuleEngine/MRE.cs b/MicroRuleEngine/MRE.cs index 2f898d2..37bfa3b 100644 --- a/MicroRuleEngine/MRE.cs +++ b/MicroRuleEngine/MRE.cs @@ -42,14 +42,30 @@ public class MRE private static readonly Lazy _miDecimalTryParse = new Lazy(() => typeof(Decimal).GetMethod("TryParse", new Type[] { typeof(string), Type.GetType("System.Decimal&") })); - public Func CompileRule(Rule r, bool useTryCatchForNulls = true) + + public Func CompileRule(Rule r) + { + return CompileRule(r, + true); + } + + + public Func CompileRule(Rule r, bool useTryCatchForNulls) { var paramUser = Expression.Parameter(typeof(T)); Expression expr = GetExpressionForRule(typeof(T), r, paramUser, useTryCatchForNulls); return Expression.Lambda>(expr, paramUser).Compile(); } - public static Expression> ToExpression(Rule r, bool useTryCatchForNulls = true) + + + public static Expression> ToExpression(Rule r) + { + return ToExpression(r, + true); + } + + public static Expression> ToExpression(Rule r, bool useTryCatchForNulls) { var paramUser = Expression.Parameter(typeof(T)); Expression expr = GetExpressionForRule(typeof(T), r, paramUser, useTryCatchForNulls); @@ -57,11 +73,26 @@ public static Expression> ToExpression(Rule r, bool useTryCatch return Expression.Lambda>(expr, paramUser); } - public static Func ToFunc(Rule r, bool useTryCatchForNulls = true) + public static Func ToFunc(Rule r) + { + return ToFunc(r, + true); + } + + public static Func ToFunc(Rule r, bool useTryCatchForNulls) { return ToExpression(r, useTryCatchForNulls).Compile(); } - public static Expression> ToExpression(Type type, Rule r, bool useTryCatchForNulls = true) + + public static Expression> ToExpression(Type type, + Rule r) + { + return ToExpression(type, + r, + true); + } + + public static Expression> ToExpression(Type type, Rule r, bool useTryCatchForNulls) { var paramUser = Expression.Parameter(typeof(object)); Expression expr = GetExpressionForRule(type, r, paramUser, useTryCatchForNulls); @@ -69,12 +100,28 @@ public static Expression> ToExpression(Type type, Rule r, boo return Expression.Lambda>(expr, paramUser); } - public static Func ToFunc(Type type, Rule r) + public static Func ToFunc(Type type, + Rule r) + { + return ToFunc(type, + r, + true); + } + + public static Func ToFunc(Type type, Rule r, bool useTryCatchForNulls) + { + return ToExpression(type, r, useTryCatchForNulls).Compile(); + } + + public Func CompileRule(Type type, + Rule r) { - return ToExpression(type, r).Compile(); + return CompileRule(type, + r, + true); } - public Func CompileRule(Type type, Rule r, bool useTryCatchForNulls = true) + public Func CompileRule(Type type, Rule r, bool useTryCatchForNulls) { var paramUser = Expression.Parameter(typeof(object)); Expression expr = GetExpressionForRule(type, r, paramUser, useTryCatchForNulls); @@ -82,14 +129,27 @@ public Func CompileRule(Type type, Rule r, bool useTryCatchForNull return Expression.Lambda>(expr, paramUser).Compile(); } - public Func CompileRules(IEnumerable rules, bool useTryCatchForNulls = true) + public Func CompileRules(IEnumerable rules) + { + return CompileRules(rules, + true); + } + + public Func CompileRules(IEnumerable rules, bool useTryCatchForNulls) { var paramUser = Expression.Parameter(typeof(T)); var expr = BuildNestedExpression(typeof(T), rules, paramUser, ExpressionType.And, useTryCatchForNulls); return Expression.Lambda>(expr, paramUser).Compile(); } - public Func CompileRules(Type type, IEnumerable rules, bool useTryCatchForNulls = true) + public Func CompileRules(Type type, IEnumerable rules) + { + return CompileRules(type, + rules, + true); + } + + public Func CompileRules(Type type, IEnumerable rules, bool useTryCatchForNulls) { var paramUser = Expression.Parameter(type); var expr = BuildNestedExpression(type, rules, paramUser, ExpressionType.And, useTryCatchForNulls);