Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6563955
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 25, 20262026-05-25T13:54:30+00:00 2026-05-25T13:54:30+00:00

So I am building a MicroRuleEngine (Would love to see this take off as

  • 0

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.

Below is the MicroRuleEngine

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;

namespace Trial
{
    public class MicroRuleEngine
    {
        public bool PassesRules<T>(List<Rule> rules, T toInspect)
        {
            bool pass = true;
            foreach (var rule in rules)
            {
                var cr = this.CompileRule<T>(rule);
                pass = pass && cr.Invoke(toInspect);
                if (!pass)
                    return pass;
            }
            return pass;
        }
        public Func<T, bool> CompileRule<T>(Rule r)
        {
            var paramUser = Expression.Parameter(typeof(T));
            Expression expr = BuildExpr<T>(r, paramUser);
            // build a lambda function User->bool and compile it

            return Expression.Lambda<Func<T, bool>>(expr, paramUser).Compile();
        }

        Expression BuildExpr<T>(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 < 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' -> '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' -> '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; }
    }
}

And This is the Test that is Failing

[TestMethod]
public void ChildPropertyRuleTest()
{
    Container container = new Container()
    {
        Repository = "TestRepo",
        Shipment = new Shipment() { OrderNumber = "555" }
    };

    MicroRuleEngine mr = new MicroRuleEngine();
    var rules = new List<Rule>() { new Rule() { MemberName = "Shipment.OrderNumber", Operator = "Contains", TargetValue = "55" } };
    var pases = mr.PassesRules<Container>(rules, container);
    Assert.IsTrue(!pases);
}
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-25T13:54:30+00:00Added an answer on May 25, 2026 at 1:54 pm

    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

    public class MicroRuleEngine
        {
            public bool PassesRules<T>(List<Rule> rules, T toInspect)
            {
                return this.CompileRules<T>(rules).Invoke(toInspect);
            }
            public Func<T, bool> CompileRule<T>(Rule r)
            {
                var paramUser = Expression.Parameter(typeof(T));
                Expression expr = BuildExpr<T>(r, paramUser);
    
                return Expression.Lambda<Func<T, bool>>(expr, paramUser).Compile();
            }
    
            public Func<T, bool> CompileRules<T>(IList<Rule> rules)
            {
                var paramUser = Expression.Parameter(typeof(T));
                List<Expression> expressions = new List<Expression>();
                foreach (var r in rules)
                {
                    expressions.Add(BuildExpr<T>(r, paramUser));
                }
                var expr = AndExpressions(expressions);
    
                return Expression.Lambda<Func<T, bool>>(expr, paramUser).Compile();
            }
    
            Expression AndExpressions(IList<Expression> expressions)
            {
                if(expressions.Count == 1)
                    return expressions[0];
                Expression exp = Expression.And(expressions[0], expressions[1]);
                for(int i = 2; expressions.Count > i; i++)
                {
                    exp = Expression.And(exp, expressions[i]);
                }
                return exp;
            }
    
            Expression BuildExpr<T>(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 < 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' -> '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' -> '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; }
        }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Building our Android app from Ant fails with this error: [apply] [apply] UNEXPECTED TOP-LEVEL
Building on the search example in this question , how would one use the
Building on this question , is there a simple solution for having a multi-key
Building on this this post , I needed a clean way to extract nodes
Building off Does Perl have an enumeration type? , how can I perform dynamic
Building my code (below) returns error 'imread' is not a member of 'cv' .
Building a website. When I order my tags like this, LightCycle works but Lightbox
building upon the $.fn.serializeObject() function from this question , i'd like to be able
Building a multi-language application in Java. Getting an error when inserting String value from
Building an app with the Facebook JavaScript API that will embedded into a page

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.