Using ExtendedFileInfo Project to avoid a System.IO.PathTooLongException.

The ExtendedFileInfo Project is a libary that you can use if you have path information longer than 248 chars and file and path information longer than 260 chars. When you search for a solution to the
System.IO.PathTooLongException: “The specified path, file name, or both are too long. The fully qualified file name must be less than 260 characters, and the directory name must be less than 248 characters.”
the ExtendedFileInfo is what you are searching for. I had the problem at a project where the path where xml configuration files where saved and the name of the xml file exceeded 260 chars. The use of that files where covered over the whole project so i had to find a global solution that uses no FileInfo class if the path and the filename where longer as 260 chars. To accomplish that i implemented the ExtendetFileInfo library and i put it to codeplex. It works the following way, if i access a file the library checks the path and if the path is too long it uses the windows api functions to access the file an no PathTooLongException is thrown. I implemented a IFileInfo interface that is used to hide the calls to the windows api or to a FileInfo object.

ExtendedFileInfo

ExtendedFileInfo class diagram

Here you see a test call that uses a short and a long path to a specific file:

[TestClass]
public class ExtendedFileInfoTest
{
    [TestMethod]
    public void ExtendedFileInfoTestShortFilePath()
    {
        var shortFilePath = @"C:\FilePath\ShortPath\Textdocument.txt";
        var extendedFileInfo = FileInfoFactory.Create(shortFilePath);
        using(var fileStream = extendedFileInfo.Open(FileMode.Open, FileAccess.Read))
        {
            var buffer = new byte[fileStream.Length];
            fileStream.Read(buffer, 0, buffer.Length);
        }
    }

    [TestMethod]
    public void ExtendedFileInfoTestLongFilePath()
    {
        var longFilePath =
            @"C:\FilePath\" + 
@"Looooooooooooooooooooooooooooooooooooooooooooooooooooooooo" + 
@"oooooooooooooooooooooooooooooooooooooooooooooooooPath\" +
@"Looooooooooooooooooooooooooooooooooooooooooooooooooooo" + 
@"ooooooooooooooooooooooooooooooooooooooooooooooooooooog\" + 
"Textdocument.txt";
        var extendedFileInfo = FileInfoFactory.Create(longFilePath);
        using (var fileStream = extendedFileInfo.Open(FileMode.Open, FileAccess.Read))
        {
            var buffer = new byte[fileStream.Length];
            fileStream.Read(buffer, 0, buffer.Length);
        }
    }
}

Extended IFileInfo interface has the following methodes and properties:

public interface IFileInfo
{
    bool Exists();
    bool IsReadOnly { get; }        
    long Length { get; }        
    string Name { get; }
    FileStream Open(FileMode fileMode, FileAccess fileAccess);
    IFileInfo CopyTo(string destFileName);        
    IFileInfo CopyTo(string destFileName, bool overwrite);
    void MoveTo(string destFileName);
    void Delete();
    void SetAttributes(FileAttributes fileAttributes);
    FileAttributes GetAttributes();
    DateTime CreationTime { get; }                
    string Extension { get; }
    string FullName { get; }
}

That means you can use all that methodes and properties like you would use it with a .net FileInfo object. So when i had that problem in my project it took me a lot of time to find the correct winapi calls and use them the correct way. So i thought if someone has the same problem it would be nice to just include a dll and the call to the FileInfo object works again.

Advertisements

Building a rule engine in c# (part 7: extending the rule engine with a like operator)

In a comment on the rule engine project (ruleengine.codeplex.com) Damien wrote that he would need a like operator in the rule engine to make string compare with wildcards possible. So i added that feature to the rule engine. You now can write “Name like ‘mathi%'” and if the Name property of an object contains the string ‘mathias’ it would return that object. Here is a test that shows the cases that are now possible with the rule engine.

[TestMethod]
public void SimpleExpressionLikeMethod()
{
    Person person1 = new Person()
    {
        Name = "mathias",
        Age = 36,
        Children = 2,
        Married = true,
        Birthdate = new DateTime(1976, 05, 09),
        CancelBenefits = false,
        ReceiveBenefits = false
    };
    Person person2 = new Person()
    {
        Name = "anna",
        Age = 32,
        Children = 2,
        Married = false,
        Birthdate = DateTime.Now,
        CancelBenefits = false,
        ReceiveBenefits = false
    };
    Evaluator evaluator = new Evaluator();
    var result1 = evaluator.Evaluate<Person>(
        " Name like 'math%' ", person1);
    Assert.AreEqual(result1, true);
    var result2 = evaluator.Evaluate<Person>(
        " Name like '?nn?' ", person2);
    Assert.AreEqual(result2, true);
    List<Person> list = new List<Person>() { person1, person2 };
    foreach(var person in list)
    {
        var result = evaluator.Evaluate<Person>(
            " Name like 'mat%' || Name like 'a??a' ", person); 
        if(result)
        {
            Debug.WriteLine(person.Name);
            Assert.AreEqual(result, true);
        }
    }
}

As you see it there are two wildcard that work. The % wildcard can only be used at the end of the text, for example “Name like ‘mat%'”. The ? wildcard can be used in the at any possition, for example “Name like ‘math?ia?'”.


Building a rule engine in c# (part 6: extentions to the rule engine)

When i started implementing the rule engine project (ruleengine.codeplex.com) it was thought as an example project. But i became some comments on the project that show that some people use the project productive and so i was asked to make some extensions to the rule engine. I am glad that someone uses my work an so i implemented the additional features. But the problem is that all that the description of that new features are spread over the comment sections of different posts. So in this post i want to summerice that features.

The first feature i was asked for by martin is that the rule engine has an is in and is not in operator. The FoundIn operator returns true if a person is in a list of given persons. The NotFoundIn operator gives back true if a person is not in a list of given persons. Here is the test i wrote to see if the operator works.

[TestMethod]
public void SimpleRuleLoaderPersonEvaluateFoundInExpression()
{
    Person person1 = new Person() { Name = "Mathias", Age = 36, Children = 2 };
    Person person2 = new Person() { Name = "Anna", Age = 35, Children = 2 };
    Person person3 = new Person() { Name = "Emil", Age = 4, Children = 0 };            

    List<Person> persons = new List<Person>();
    persons.Add(person1);
    persons.Add(person2);

    RuleEngine.RuleEngine ruleEngine = new RuleEngine.RuleEngine();
    var ruleFunc =
        ruleEngine.CompileRule<Person>("Name", Operator.FoundIn, persons);
    var result = ruleFunc(person1);

    Rule<Person> rule = new Rule<Person>("Name", Operator.NotFoundIn, persons);
    var ruleFuncRule =
        ruleEngine.CompileRule<Person>(rule);

    var ruleFuncRuleResult = ruleFuncRule(person3);
    Assert.AreEqual(result, true); 
    Assert.AreEqual(ruleFuncRuleResult, false);
}

To implement that operator i had build a expression tree that is more complex that the simple one for Equal, Unequal, SmallerThen etc. Here is the code that builds the expression tree to check if a person with a given attribute is in a list of persons.

public Tuple<Expression, 
ParameterExpression> BuildExpression<T>(string propertyName, Operator ruleOperator, 
    ParameterExpression parameterExpression, List<T> values)
{                    
    ParameterExpression listExpression = Expression.Parameter(typeof(List<T>));
    ParameterExpression counterExpression = 
Expression.Parameter(typeof(int));
    ParameterExpression toExpression = Expression.Parameter(typeof(int));
    ParameterExpression arrayExpression = Expression.Parameter(typeof(T[]));
    ParameterExpression valueExpression = Expression.Parameter(typeof(T));
    ParameterExpression checkExpression = Expression.Parameter(typeof(T));
    ParameterExpression returnExpression = 
Expression.Parameter(typeof(bool));
    MemberExpression memberExpression = MemberExpression.Property(parameterExpression, propertyName);
    Expression expression = memberExpression.Expression;
    var type = memberExpression.Type;
    ParameterExpression propertyExpression = Expression.Parameter(type);
    ParameterExpression localPropertyExpression = Expression.Parameter(type);

    LabelTarget breakLabel = Expression.Label();
    PropertyInfo result = typeof(List<T>).GetProperty("Count");
    MethodInfo toArray = typeof(List<T>).GetMethod("ToArray");
    var toArrayName = toArray.Name;
    MethodInfo getGetMethod = result.GetGetMethod();
    ConstantExpression constantExpression = Expression.Constant(true);
    if (ruleOperator == Operator.NotFoundIn)
    {
        constantExpression = Expression.Constant(false);
    }
    Expression loop = Expression.Block(
        new ParameterExpression[] { 
toExpression, arrayExpression, valueExpression, counterExpression, 
        returnExpression, propertyExpression, localPropertyExpression, listExpression },
        Expression.Assign(listExpression, Expression.Constant(values)),
        Expression.Assign(toExpression, Expression.Call(listExpression, getGetMethod)),
        Expression.Assign(arrayExpression, Expression.Call(listExpression, toArray)),
        Expression.Assign(propertyExpression, MemberExpression.Property(checkExpression, propertyName)),
        Expression.Loop(
            Expression.IfThenElse(
                Expression.LessThan(counterExpression, toExpression),
                Expression.Block(
                    Expression.Assign(valueExpression, 
Expression.ArrayAccess(arrayExpression, counterExpression)),
                    Expression.Assign(localPropertyExpression, 
Expression.Property(valueExpression, propertyName)),
                    Expression.IfThen(
                        Expression.Equal(propertyExpression, localPropertyExpression),
                        Expression.Block(Expression.Assign(returnExpression, constantExpression),
                            Expression.Break(breakLabel))),
                    Expression.Assign(
Expression.ArrayAccess(arrayExpression, counterExpression), checkExpression),
                    Expression.PostIncrementAssign(counterExpression)),
                Expression.Break(breakLabel)
                ), breakLabel
            ),
            Expression.And(returnExpression, constantExpression)
        );
    return new Tuple<Expression, ParameterExpression>(Expression.Block(loop), checkExpression);
}

This code builds a loop that enumerates a list of objects and checks a specified property (localPropertyExpression specified by propertyName) has the same value as the propertyExpression. If the values are the same the returnExpression is set to true. (if it is the NotFoundIn operator it is set to false). The CompileRule call looks the following:

public Func<T, bool> CompileRule<T>(string propertyName, 
    Operator ruleOperator, List<T> values)
{
    ExpressionBuilder expressionBuilder = new ExpressionBuilder();
    var param = Expression.Parameter(typeof(T));
    Tuple<Expression, ParameterExpression> expression =
        expressionBuilder.BuildExpression<T>(propertyName, ruleOperator, param, values);
    Func<T, bool> compiledExpression = Expression.Lambda<Func<T, bool>>(
        expression.Item1, expression.Item2).Compile();
    return compiledExpression;
}

The differnece to all the other CompileRule methodes is that it takes a list of values. That list of values becomes iterated in the expression tree.

The second feature i was asked for by Mike is that he needed to call a method at the person object if a specific  property of the person has a specific value. The problem was that he needed that in the expression evaluator string. The following code shows what he needed.

var tuple = evaluator.Evaluate<Person>(
                " (Age < 10) then SetCanReceiveBenefits(true) else SetCancelBenefits(true) ");

To check if the evaluation works correct i have added two methodes (SetCanReceiveBenefits and SetCancelBenefits) to the person object.

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
    public int Children { get; set; }
    public bool Married { get; set; }
    public DateTime Birthdate { get; set; }
    public Adresse Adresse_ { get; set; }
    public bool ReceiveBenefits { get; set; }
    public bool CancelBenefits { get; set; }
    public void SetCanReceiveBenefits(bool receiveBenefits)
    {
        ReceiveBenefits = receiveBenefits;
    }
    public void SetCancelBenefits(bool cancelBenefits)
    {
        CancelBenefits = cancelBenefits;
    }
    private List<Adresse> adresses = new List<Adresse>();
    public List<Adresse> Adresses_ 
    { 
        get { return adresses; } 
        set { adresses = value; } 
    }
}

After that i had to change the lexer and the parser of the evaluation evaluator to handle the then and else keyword. Here is the complete test that shows how to use the then and else keyword.

[TestMethod]
public void SimpleExpressionEvaluatorWithThenMethod()
{
    Person person1 = new Person()
    {
        Name = "Mathias",
        Age = 36,
        Children = 2,
        Married = true,
        Birthdate = new DateTime(1976, 5, 9),
        CancelBenefits = false,
        ReceiveBenefits = false
    };            
    Evaluator evaluator = new Evaluator();
    bool result = evaluator.Evaluate(
        " (Age > 10) then SetCanReceiveBenefits(true) ", person1);
    Assert.AreEqual(person1.ReceiveBenefits, true);
}

Here is the test that shows how the else keyword works.

[TestMethod]
public void SimpleExpressionPreEvaluatorWithThenAndElseMethod()
{
    Person person1 = new Person()
    {
        Name = "Mathias",
        Age = 36,
        Children = 2,
        Married = true,
        Birthdate = new DateTime(1976, 5, 9),
        CancelBenefits = false,
        ReceiveBenefits = false
    };
    Evaluator evaluator = new Evaluator();
    bool result = evaluator.Evaluate(
         " (Age < 10) then SetCanReceiveBenefits(true) else SetCancelBenefits(true) ", person1);
    Assert.AreEqual(person1.CancelBenefits, true);
}

Mike also wrote that he needs the rule engine to work with many objects and asked if it is possible that the rule engine could preprocess the evaluation of the expression. So i splitted the evaluation process and added the PreEvalute method to preprocess the evaluation of the evaluation string and the building of the symbol table. The ExecuteEvaluate method takes the prepocessed abstract syntax tree and the symbol table and does only the evaluation with the given object. Her is a test that shows that preprocessing step.

[TestMethod]
public void SimpleExpressionPreEvaluatorWithThenElseMethod()
{
    Person person1 = new Person()
    {
        Name = "Mathias",
        Age = 36,
        Children = 2,
        Married = true,
        Birthdate = new DateTime(1976, 5, 9),
        CancelBenefits = false,
        ReceiveBenefits = false
    };
    Person person2 = new Person()
    {
        Name = "Anna",
        Age = 32,
        Children = 2,
        Married = false,
        Birthdate = new DateTime(2002, 2, 2),
        CancelBenefits = false,
        ReceiveBenefits = false
    };
    Evaluator evaluator = new Evaluator();
    var tuple = evaluator.PreEvaluate(
        " (Age < 10) then SetCanReceiveBenefits(true) else SetCancelBenefits(true) ");
    evaluator.ExecuteEvaluate(tuple, person1);
    evaluator.ExecuteEvaluate(tuple, person2);
    Assert.AreEqual(person1.CancelBenefits, true);
    Assert.AreEqual(person2.CancelBenefits, true);
}

If you use rule engine in a real project that could save a lot of time because the evaluation needs some time and repeats over and over again if you use the normal evaluate method.

The third feature i was asked for by Damian, and he needed to check if a specific property is null. So i implemented the is null operator. The problem is that in c# value types like int can not take null so this operator works only correct with strings. The following test shows how the is null operator works.

[TestMethod]
public void SimpleExpressionStringIsNullMethod()
{            
    Person person2 = new Person()
    {
        Name = null,
        Age = 32,
        Children = 2,
        Married = false,
        Birthdate = new DateTime(2002, 2, 2),
        CancelBenefits = false,
        ReceiveBenefits = false
    };
    Evaluator evaluator = new Evaluator();
    var result = evaluator.Evaluate(
        " Name is null ", person2);
    Assert.AreEqual(result, true);            
}

So if you want to use the rule engine in real world projects i hope that helps to check all rules you have to check.


Distinct a DataTable with c#

Today i want to write about the different possibilities to distinct the data in a DataTable. I had that problem some times ago and searched for a good solution. I found some different solutions and in that post i will show them. First i want to show the test i wrote to test the distinct of the DataTable and the data stored in the DataTable.

[TestMethod]
public void Distinct()
{
    DataTable dataTable = new DataTable("Distinct");
    var oldPK = new DataColumn() { ColumnName = "PK", DataType = typeof(int) };
    dataTable.Columns.Add(oldPK);
    var secondPK = new DataColumn() { ColumnName = "secondPK", DataType = typeof(int) };
    dataTable.Columns.Add(secondPK);
    dataTable.Columns.Add(new DataColumn() 
        { ColumnName = "firstname", DataType = typeof(string) });
    dataTable.Columns.Add(new DataColumn() 
        { ColumnName = "secondname", DataType = typeof(string) });
    dataTable.Columns.Add(new DataColumn() 
        { ColumnName = "socialSecurityNumber", DataType = typeof(int) });
    dataTable.PrimaryKey = new DataColumn[] { oldPK, secondPK };
    foreach (var number in Enumerable.Range(1, 3))
    {
        DataRow dataRow = dataTable.NewRow();
        dataRow["PK"] = number;
        dataRow["secondPK"] = number + 1;
        dataRow["firstname"] = "mathias";
        dataRow["secondname"] = "schober";
        dataRow["socialSecurityNumber"] = 4040;
        dataTable.Rows.Add(dataRow);
    }
    foreach (var number in Enumerable.Range(4, 2))
    {
        DataRow dataRow = dataTable.NewRow();
        dataRow["PK"] = number;
        dataRow["secondPK"] = number + 1;
        dataRow["firstname"] = "anna";
        dataRow["secondname"] = "schober";
        dataRow["socialSecurityNumber"] = 5050;
        dataTable.Rows.Add(dataRow);
    }
    var newDataTable = 
        dataTable.Distinct("socialSecurityNumber");
    var newDataViewDataTable = 
        dataTable.DistinctDataView("socialSecurityNumber");
    var newEqualityCompareDataTable = 
        dataTable.DistinctEqualityCompare("socialSecurityNumber");
    var newGenericEqualityCompareDataTable = 
        dataTable.DistinctGenericEqualityCompare("socialSecurityNumber");         
}

DistinctDataTable
As we see i wrote four different methods to distinct the DataTable. The first on Distinct is the classical way. I create a new DataTable, take the original DataTable, enumerate all rows and check if the value of the overtaken column (in the test i use socialSecurityNumber) is already in the new DataTable. Then i set the primary key of the new DataTable and reorder the columns to bring the primary key (overtaken column) to the first position. Here you see the code to do so.

public static class Distincting
{
    public static DataTable Distinct(this DataTable dataTable, 
        string columName)
    {
        DataColumn[] dataColumns = dataTable.PrimaryKey;
        if (dataColumns.Length >= 1)
        {
            foreach (DataColumn primaryKey in dataColumns)
            {
                if (primaryKey.ColumnName == columName)
                {
                    return dataTable;
                }                    
            }                
        }            
        return RebuildDataTable(dataTable, columName);
    }

    private static DataTable RebuildDataTable(DataTable dataTable, 
        string columName)
    {
        DataTable newDataTable = dataTable.Clone();
        DataColumn newDataColumn = newDataTable.Columns[columName];
        newDataTable.PrimaryKey = new DataColumn[] { newDataColumn };
        newDataTable.Columns[columName].SetOrdinal(0);
        dataTable.Rows.Foreach(dataRow =>
        {
            object pk = dataRow[columName];
            if (newDataTable.Rows.Find(pk) == null)
            {
                newDataTable.ImportRow(dataRow);
            }
        });
        ReorderPrimaryKey(dataTable, newDataTable);
        return newDataTable;
    }

    private static void ReorderPrimaryKey(DataTable dataTable, 
        DataTable newDataTable)
    {
        int maxOrdinal = 0;
        foreach (DataColumn column in newDataTable.Columns)
        {
            if (column.Ordinal > maxOrdinal)
                maxOrdinal = column.Ordinal;
        }
        DataColumn[] dataColumns = dataTable.PrimaryKey;
        if (dataColumns.Length >= 1)
        {
            foreach (DataColumn primaryKey in dataColumns)
            {
                newDataTable.Columns[primaryKey.ColumnName].
                    SetOrdinal(maxOrdinal);
            }
        }
    }
}
public static class ForEachEnumeration
{
    public static void Foreach(this DataRowCollection dataRows, 
Action action)
    {
        foreach(T dataRow in dataRows)
        {
            action(dataRow);
        }
    }
}

After distincting with the social sercurity number we have the following DataTable.
DistinctDataTableVersion1

The second possibility to distinct a DataTable is using the ToTable method of the DataView. In the next code part you can see how that works.

public static DataTable DistinctDataView(this DataTable dataTable,
        string columName)
{
    DataView view = new DataView(dataTable);
    return view.ToTable(true, new string[] { columName });
}

That is the resulting DataTable. As we see it contains only the social security number. The other columns are gone.
DistinctDataTableVersion2

After the classic version and the DataView version it is also possible to solve the problem with the linq Distinct Extension method.

public static DataTable DistinctEqualityCompare(this DataTable dataTable, 
    string columName)
{
    DataRowEqaulityComparer dataRowEqualityComparer = 
        new DataRowEqaulityComparer(columName);
    return dataTable.AsEnumerable().
        Distinct(dataRowEqualityComparer).CopyToDataTable();
}

To accomplish that we need a EqualityComparer.

public class DataRowEqualityComparer : IEqualityComparer
{
    private string distinctColumnName;

    public DataRowEqualityComparer(string distinctColumnName)
    {
        this.distinctColumnName = distinctColumnName;
    }

    public bool Equals(DataRow x, DataRow y)
    {
        if (x.Field<object>(distinctColumnName).
            Equals(y.Field<object>(distinctColumnName)))
        {
            return true;
        }
        return false;
    }

    public int GetHashCode(DataRow obj)
    {
        return obj.Field<object>(distinctColumnName).GetHashCode();
    }
}

Or we could also use a Generic EqualityComparer. (implementing a generic IEqualityComparer and IComparer class)

public static DataTable DistinctGenericEqualityCompare(this DataTable dataTable,
    string columName)
{
    EqualityComparer dataRowEqualityComparer = 
        new EqualityComparer(
        (x, y) => x.Field<object>(columName).Equals(y.Field<object>(columName)),
        x => x.Field<object>(columName).GetHashCode()
        );
    return dataTable.AsEnumerable().
        Distinct(dataRowEqualityComparer).CopyToDataTable();
}
public class EqualityComparer : IEqualityComparer
{
    private Func<T, T, bool> equalsFunction;
    private Func<T, int> getHashCodeFunction;

    public EqualityComparer(Func<T, T, bool> equalsFunction)
    {
        this.equalsFunction = equalsFunction;
    }

    public EqualityComparer(Func<T, T, bool> equalsFunction,
        Func<T, int> getHashCodeFunction)
        : this(equalsFunction)
    {
        this.getHashCodeFunction = getHashCodeFunction;
    }

    public bool Equals(T a, T b)
    {
        return equalsFunction(a, b);
    }

    public int GetHashCode(T obj)
    {
        if (getHashCodeFunction == null)
            return obj.GetHashCode();
        return getHashCodeFunction(obj);
    }
}

That is the resulting DataTable.
DistinctDataTableVersion3
That are all possibilities i could think of to distinct a DataTable.


Building a rule engine in c# (part 5: bringing it all together)

In the first four post of these series i showed a lot of code parts. I became some mails about that posts that show me that my descriptions are not as good as i thought. For that reason i decided to write that fifth post to bring it all together. First of all i decided to bring the source code of the posts together and so i created the ruleengine project at ruleengine.codeplex.com. Here are the links to the four previous posts and to the description of the expression evaluator.

Now i want to describe the tests i added to the ruleengine.codeplex.com project to show how to use ist. First i want to show the Person and Adress classed i use to validate the rules against:

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
    public int Children { get; set; }
    public bool Married { get; set; }
    public Adresse Adresse_ { get; set; }
    private List<Adresse> adresses = new List<Adresse>();
    public List<Adresse> Adresses_ 
    { 
        get { return adresses; } 
        set { adresses = value; } 
    }
}

The Person class has some properties (Name, Age, Children, Married) and a collection of Adresses.

public class Adresse
{
    public string Street { get; set; }
    public int Plz { get; set; }
    public string City { get; set; }
    public bool ActiveState { get; set; }
}

The Adress class has some simple properties (Stree, Plz, City, ActiveState).
I will start with a simple test case to test a persons properties against a specific rule.

[TestMethod]
public void SimpleRuleLoaderPersonTest()
{
    Person person = new Person() { Name = "Mathias", Age = 36, Children = 2, Married = true };
    RuleLoader ruleLoader = new RuleLoader();
    // new Rule("Age", Operator.LessThanOrEqual, 50);
    Rule rule = ruleLoader.Load(2);
    RuleEngine.RuleEngine ruleEngine = new RuleEngine.RuleEngine();
    var ruleFunc = ruleEngine.CompileRule<Person>(rule);
    var result = ruleFunc(person);
    Assert.AreEqual(result, true);
}

That test defines a Person object and instanciates a RuleLoader object. That ruleLoader object would load the rules from the database but in my special case i wanted to use no database so the rule Loader is just a big switch statement that creates rules:

public class RuleLoader
{
    public Rule Load(int id)
    {            
        switch(id)
        {
            case 1 : 
                return new Rule("Name", Operator.NotEqual, "test");
            case 2 : 
                return new Rule("Age", Operator.LessThanOrEqual, 50);
            case 3: 
                return new Rule("Children", Operator.GreaterThan, 0);
            case 4: 
                return new Rule("City", Operator.Equal, "New York");
            case 5: return 
                new Rule("ActiveState", Operator.Equal, true);                
            case 6: 
                return new Rule("DecimalValue", Operator.GreaterThanOrEqual, 1);
            case 7: 
                return new Rule("DecimalValue", Operator.GreaterThanOrEqual, 1);
            case 8: 
                return new Rule("Married", Operator.Equal, true);
            default :
                return null;
        }
    }        
}

After that i use the RuleEngine to build a Func delegate out of the defined rule. In this case it is a Func of Person, bool delegate. This delegate gets invoked with the Person object as parameter and returns true or false. The second test shows how to use the RuleValidator class. That class has defined different ValidatorRule methodes to validate objects against rules.

[TestMethod]
public void SimpleRuleLoaderPersonValidateRulesAny()
{
    Person person1 = new Person() { 
        Name = "Mathias", Age = 36, Children = 2, Married = true };
    Person person2 = new Person() { 
        Name = "Anna", Age = 32, Children = 2, Married = false };
    RuleLoader ruleLoader = new RuleLoader();
    // new Rule("Age", Operator.LessThanOrEqual, 50);
    Rule rule1 = ruleLoader.Load(2);
    // new Rule("Children", Operator.GreaterThan, 0);
    Rule rule2 = ruleLoader.Load(3);
    RuleEngine.RuleEngine ruleEngine = new RuleEngine.RuleEngine();
    var ruleFuncs = ruleEngine.CombineRules<Person>(
        new Rule[] { rule1, rule2 });
    RuleValidator ruleValidator = new RuleValidator();
    var result = ruleValidator.ValidateRulesAny(
        new[] { person1, person2 }, ruleFuncs);
    Assert.AreEqual(result, true);
}

In this case we use the CombineRules method of the RuleEngine to create an array of Func delegates. That delegates and the two Person objects are overtaken to the ValidateRulesAny method of the RuleValidator. That method returns true if every person fulfills at least one rule. The next test shows how to use the RuleEngine to validate collections of objects against rules.

[TestMethod]
public void SimpleRuleLoaderPersonAddressValidateRulesAll()
{
    Person person = new Person() { 
        Name = "Mathias", Age = 36, Children = 2, Married = true };
    Adresse adresseOne = new Adresse() { 
        Street = "Teststreet1", Plz = 3030, City = "New York", ActiveState = true };
    Adresse adresseTwo = new Adresse() { 
        Street = "Teststreet2", Plz = 1010, City = "London", ActiveState = false };
    Adresse adresseThree = new Adresse() { 
        Street = "Teststreet3", Plz = 2020, City = "Paris", ActiveState = false };        
    person.Adresses_.Add(adresseOne);
    person.Adresses_.Add(adresseTwo);
    person.Adresses_.Add(adresseThree);
    RuleLoader ruleLoader = new RuleLoader();
    // new Rule("City", Operator.Equal, "New York");
    Rule firstAdressRule = ruleLoader.Load(4);
    // new Rule("ActiveState", Operator.Equal, true);      
    Rule secondAdressRule = ruleLoader.Load(5);
    RuleEngine.RuleEngine ruleEngine = new RuleEngine.RuleEngine();
    var firstAdressRuleFunc = 
        ruleEngine.CompileRule<Adresse>(firstAdressRule);
    var secondAdressRuleFunc = 
        ruleEngine.CompileRule<Adresse>(secondAdressRule);
    RuleValidator ruleValidator = new RuleValidator();
    bool result = ruleValidator.
        ValidateValuesAny(person.Adresses_, firstAdressRuleFunc);
    Assert.AreEqual(result, true);
    result = ruleValidator.
        ValidateValuesAny(person.Adresses_, secondAdressRuleFunc);            
    Assert.AreEqual(result, true);
}

Here the Person objects owns a List of Adress objects. The RuleValidator class has some methods that take a List and validates every element of that list against a rule.(ruleValidator.ValidateValuesAny(person.Adresses_, firstAdressRuleFunc) ). The next test shows how the ruleEngine sums up a property and validates this sum against two rules.

[TestMethod]
public void SimpleRuleLoaderPersonValidateRulesSum()
{
    Person person1 = new Person() { 
        Name = "Mathias", Age = 35, Children = 2 };
    Person person2 = new Person() { 
        Name = "Anna", Age = 32, Children = 2 };
    RuleLoader ruleLoader = new RuleLoader();
    // new Rule("Age", Operator.LessThanOrEqual, 50);
    Rule rule1 = ruleLoader.Load(2);
    // new Rule("Children", Operator.GreaterThan, 0);
    Rule rule2 = ruleLoader.Load(3);
    RuleValidator ruleValidator = new RuleValidator();
    var result = ruleValidator.ValidateRulesSum(
        new Person[] { person1, person2 },
        new Rule[] { rule1, rule2 });            
    Assert.AreEqual(result, false);
}

Here is use the ValidateRulesSum method. This method takes an array of objects (person1, person2) and an array of rules (rule1, rule2). It takes the first rule checks what property of the Person object this rule uses, sums up that property value of all overtaken objects and checks that sum against the rule. It returns true if the sum of all properties pass all rules. The next test shows the usage of the expression evaluator rules. In this case the Rules are expression rules ( like ” Name = ‘mathias’ “).

[TestMethod]
public void SimpleRuleLoaderPersonEvaluateExpression()
{
    Person person1 = new Person() 
        { Name = "Mathias", Age = 35, Children = 2 };
    ExpressionRuleLoader expressionRuleLoader = new ExpressionRuleLoader();
    // new Rule(" Name = 'mathias' ");
    Rule rule1 = expressionRuleLoader.Load(1);
    // new Rule(" Age = 35 ");
    Rule rule2 = expressionRuleLoader.Load(2);           
    RuleValidator ruleValidator = new RuleValidator();
    var result = ruleValidator.ValidateExpressionRules(person1, rule1);
    Assert.AreEqual(result, true);
    result = ruleValidator.ValidateExpressionRules(person1, rule2);
    Assert.AreEqual(result, true);
}

The RuleValidator class has methodes (e.g. ValidateExpressionRules) to validate the Expression Rules against objects. In this case the rules are ” Name = ‘Mathias’ ” and ” Age = 35 “. To look what the expression evaluator can afford and what not please look at my the implementing expression evaluator in c# post.
The source code of the expression evaluator is part of the ruleengine.codeplex.com project and can also be downloaded from simpleexpeval.codeplex.com.


Building a rule engine in c# (part 3: extending the rule engine to handle aggregations of collections)

In had a comment on my post about building a rule engine in c#. The question in this comment was how to handle aggregations within the rule engine. In this post i try to give one example how to handle aggregations. I will show a possible way to include sum and average in the rule engine and to look if the aggregated property of the property of a collection of objects corresponds one or many of the defined rules. I wrote two post about the topic building a rule engine in c# and building a rule engine in c# (part 2: extending the rule engine to handle collections). Now i will extend the RuleValidator i implemented in the second post with two methods that can handle the sum and average. This are the rules in the database:

ProcessingEngineDatabase

Now i have a list of Person objects and want to know if the sum of all children are greater than zero and the sum of the age of all Person objects is Less than or equal 50. So in that case the result is false because the second rule (Age <= 50) failes.

Person person1 = new Person() { Name = "Mathias", Age = 35, Children = 2 };
Person person2 = new Person() { Name = "Anna", Age = 32, Children = 2 };
RuleValidator ruleValidator = new RuleValidator();
var sum = ruleValidator.ValidateRulesSum(
    new Person[] { person1, person2 }, 
    new Rule[] { firstRule, secondRule });

The ValidateRulesSum method call sums up the values of the property that is relevant for the overtaken rule and then checks the rule with the calculated sum.. To do so i need some reflection and the dynamic keyword to handle different types. (Int32, Double etc.). So thats how the ValidateRulesSum and the ValidateRulesAvg methodes look like.

public bool ValidateRulesSum<T>(IEnumerable<T> values, IEnumerable<Rule> rules)
{
    foreach (var rule in rules)
    {
        // necessary to create the type dynamic so i could use the + operator to 
        // build the sum on an Int32 or Double or Decimal
        dynamic sum = Activator.CreateInstance(
            values.GetType().GetElementType().GetProperty(rule.PropertyName).PropertyType);
        foreach (var value in values)
        {
            dynamic innerValue = value.GetType().
                GetProperty(rule.PropertyName).GetValue(value, null);
            // creating the sum
            sum += innerValue;
        }
        // building the Func
        dynamic func = BuildGenericFunction(rule, sum);
        // checking the rule Func with the sum value
        if (!func(sum))
            return false;                
    }
    return true;
}
public bool ValidateRuleAvg<T>(IEnumerable<T> values, IEnumerable<Rule> rules)
{
    foreach (var rule in rules)
    {
        dynamic sum = Activator.CreateInstance(values.GetType().
            GetElementType().GetProperty(rule.PropertyName).PropertyType);
        var counter = 0;
        foreach (var value in values)
        {
            dynamic innerValue = value.GetType().
                GetProperty(rule.PropertyName).GetValue(value, null);
            sum += innerValue;
            counter++;
        }
        dynamic avg = sum / counter;
        dynamic func = BuildGenericFunction(rule, avg);
        if (!func(avg))
            return false;
    }
    return true;
}
private object BuildGenericFunction(Rule rule, object sum)
{
    ExpressionBuilder expressionBuilder = new ExpressionBuilder();
    System.Type specificType = sum.GetType();
    var param = Expression.Parameter(specificType);
    Expression expression = expressionBuilder.
        BuildExpression(specificType, rule.Operator_, rule.Value, param);
    // creates the generic type so i can make a call with the type of 
    // the property to the BuildLambdaFunc function
    MethodInfo method = this.GetType().GetMethod("BuildLambdaFunc", 
        BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
    MethodInfo generic = method.MakeGenericMethod(specificType);
    object func = generic.Invoke(this, new object[] { expression, param });
    return func;
}

private Func<T, bool> BuildLambdaFunc<T>(
    Expression expression, ParameterExpression param)
{
    // building the lambda function
    Func<T, bool> func = Expression.Lambda<Func<T, bool>>
        (expression, param).Compile();
    return func;
}

The code is straight fourward but to get out the type of the property of the Person object that is defined in the Rule (e.g. Age) i need the MakeGenericMethod method of the MethodInfo type and that i have to use the Invoke method to invoke the dynamic created method. That is necessary because the BuildLambdaFunc method has a generic type T definied and i need to overtake the type of the property of the Person object (e.g. Int32 for Age). So with the reflection method MakeGenericMethod i can build the method with the generic type T. I dont need to know the type at compile time i can find it out at runtime. In the fourth part of this blog series i write about implementing an expression evaluator to define more complex expressions. (Building a rule engine in c# (part 4: extending the rule engine to evaluate defined expressions)) and in the fifth part building a rule engine in c# (part 5: bringing it all together) i give an overview about the usage of the ruleengine.codeplex.com project i created to bring the code parts in that post series together.