Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>So the error I was running into was all the examples I read in trying to find out how to access sub properties were using MemberAccess Expressions to walk down the properties and I found that using PropertyExpressions worked without a problem for the simple tests I have. Below is an update that is now working</p> <pre><code>public class MicroRuleEngine { public bool PassesRules&lt;T&gt;(List&lt;Rule&gt; rules, T toInspect) { return this.CompileRules&lt;T&gt;(rules).Invoke(toInspect); } public Func&lt;T, bool&gt; CompileRule&lt;T&gt;(Rule r) { var paramUser = Expression.Parameter(typeof(T)); Expression expr = BuildExpr&lt;T&gt;(r, paramUser); return Expression.Lambda&lt;Func&lt;T, bool&gt;&gt;(expr, paramUser).Compile(); } public Func&lt;T, bool&gt; CompileRules&lt;T&gt;(IList&lt;Rule&gt; rules) { var paramUser = Expression.Parameter(typeof(T)); List&lt;Expression&gt; expressions = new List&lt;Expression&gt;(); foreach (var r in rules) { expressions.Add(BuildExpr&lt;T&gt;(r, paramUser)); } var expr = AndExpressions(expressions); return Expression.Lambda&lt;Func&lt;T, bool&gt;&gt;(expr, paramUser).Compile(); } Expression AndExpressions(IList&lt;Expression&gt; expressions) { if(expressions.Count == 1) return expressions[0]; Expression exp = Expression.And(expressions[0], expressions[1]); for(int i = 2; expressions.Count &gt; i; i++) { exp = Expression.And(exp, expressions[i]); } return exp; } Expression BuildExpr&lt;T&gt;(Rule r, ParameterExpression param) { Expression propExpression; Type propType; ExpressionType tBinary; if (r.MemberName.Contains('.')) { String[] childProperties = r.MemberName.Split('.'); var property = typeof(T).GetProperty(childProperties[0]); var paramExp = Expression.Parameter(typeof(T), "SomeObject"); propExpression = Expression.PropertyOrField(param, childProperties[0]); for (int i = 1; i &lt; childProperties.Length; i++) { property = property.PropertyType.GetProperty(childProperties[i]); propExpression = Expression.PropertyOrField(propExpression, childProperties[i]); } propType = propExpression.Type; } else { propExpression = Expression.PropertyOrField(param, r.MemberName); propType = propExpression.Type; } // is the operator a known .NET operator? if (ExpressionType.TryParse(r.Operator, out tBinary)) { var right = Expression.Constant(Convert.ChangeType(r.TargetValue, propType)); // use a binary operation, e.g. 'Equal' -&gt; 'u.Age == 15' return Expression.MakeBinary(tBinary, propExpression, right); } else { var method = propType.GetMethod(r.Operator); var tParam = method.GetParameters()[0].ParameterType; var right = Expression.Constant(Convert.ChangeType(r.TargetValue, tParam)); // use a method call, e.g. 'Contains' -&gt; 'u.Tags.Contains(some_tag)' return Expression.Call(propExpression, method, right); } } } public class Rule { public string MemberName { get; set; } public string Operator { get; set; } public string TargetValue { get; set; } } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload