title: Building a MicroRuleEngine using LinqExpressions
body: <p>So I am building a MicroRuleEngine (Would love to see this take off as an OpenSource project) and I am running into a null reference Error When executing the compiled ExpressionTree and I am not exactly sure why.  Rules against the simple properties work but going against Child Properties aka Customer.Client.Address.StreetName etc. do not work.</p>
  
  <p>Below is the MicroRuleEngine</p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Text;
  using System.Linq.Expressions;
  
  namespace Trial
  {
      public class MicroRuleEngine
      {
          public bool PassesRules&lt;T&gt;(List&lt;Rule&gt; rules, T toInspect)
          {
              bool pass = true;
              foreach (var rule in rules)
              {
                  var cr = this.CompileRule&lt;T&gt;(rule);
                  pass = pass &amp;&amp; cr.Invoke(toInspect);
                  if (!pass)
                      return pass;
              }
              return pass;
          }
          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);
              // build a lambda function User-&gt;bool and compile it
  
              return Expression.Lambda&lt;Func&lt;T, bool&gt;&gt;(expr, paramUser).Compile();
          }
  
          Expression BuildExpr&lt;T&gt;(Rule r, ParameterExpression param)
          {
              Expression propExpression;
              Type propType;// typeof(T).GetProperty(r.MemberName).PropertyType;
              ExpressionType tBinary;
              if (r.MemberName.Contains('.'))
              {
                  // support to be sorted on child fields.
                  String[] childProperties = r.MemberName.Split('.');
                  var property = typeof(T).GetProperty(childProperties[0]);
                  var paramExp = Expression.Parameter(typeof(T), "SomeObject");
                  propExpression = Expression.MakeMemberAccess(paramExp, property);
                  for (int i = 1; i &lt; childProperties.Length; i++)
                  {
                      property = property.PropertyType.GetProperty(childProperties[i]);
                      propExpression = Expression.MakeMemberAccess(propExpression, property);
                  }
                  propType = propExpression.Type;
                  propExpression = Expression.Block(new[] { paramExp }, new[]{ propExpression });
  
              }
              else
              {
                  propExpression = MemberExpression.Property(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>
  
  <p>And This is the Test that is Failing</p>
  
  <pre><code>[TestMethod]
  public void ChildPropertyRuleTest()
  {
      Container container = new Container()
      {
          Repository = "TestRepo",
          Shipment = new Shipment() { OrderNumber = "555" }
      };
  
      MicroRuleEngine mr = new MicroRuleEngine();
      var rules = new List&lt;Rule&gt;() { new Rule() { MemberName = "Shipment.OrderNumber", Operator = "Contains", TargetValue = "55" } };
      var pases = mr.PassesRules&lt;Container&gt;(rules, container);
      Assert.IsTrue(!pases);
  }
  </code></pre>