Dynamic Expressions

While working on a recent project I wanted to implement some kind of expression rule within a database so that it was easy for end users to read and understand the expressions and also make changes if necessary.

While searching about for something similar I came across the LINQDynamic Query Library. This library enables you to turn text into LINQ queries - BINGO! that's exactly what I need and somebody has already done all the hard work.

So best way to show it off is a quick example, you should be able to copy this and run it as a console app:-

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

namespace LambdaExpressions
{
    class TravellerCounts
    {
        public int Adults { get; set; }
        public int Infants { get; set; }
    }

    class Program
    {
        static readonly Dictionary Expressions = new Dictionary(); 

        private static void CreateCompiledExpressions()
        {
            
            // Would normally be loading these from Database/File/External Source
            Expressions.Clear();

            var type = Type.GetType("LambdaExpressions.TravellerCounts");

            var @params = new[] { System.Linq.Expressions.Expression.Parameter(type, "") };
            var parser = new ExpressionParser(@params, "infants = 3", null);
            var lambda = System.Linq.Expressions.Expression.Lambda(parser.Parse(typeof(bool)), @params);
            
            // IEQ3 = Infants Equals 3
            Expressions.Add("IEQ3", lambda.Compile());

            parser = new ExpressionParser(@params, "infants + adults < 9", null);
            lambda = System.Linq.Expressions.Expression.Lambda(parser.Parse(typeof(bool)), @params);

            // TTCLT9 = Total Traveller Count Less Than 9
            Expressions.Add("TTCLT9", lambda.Compile());

        } 

        static void Main(string[] args)
        {
            // Create all of our compiled expressions to use wherever needed 
            CreateCompiledExpressions();
 
            // Create the object that we want to test
            TravellerCounts counts = new TravellerCounts { Adults = 10, Infants = 2};

            // Now check if the object matches the pre-compiled IEQ3 expression
            if ((bool)Expressions["IEQ3"].DynamicInvoke(counts))
            {
                Console.WriteLine("Match found IEQ3");
            }
            else
            {
                Console.WriteLine("Match NOT found IEQ3");
            }

            // Or does it match the TTCLT9 expression
            if ((bool)Expressions["TTCLT9"].DynamicInvoke(counts))
            {
                Console.WriteLine("Match found TTCLT9");
            }
            else
            {
                Console.WriteLine("Match NOT found TTCLT9");
            }

            Console.ReadLine();

        }
    }
}

0 comments: