Building a rule engine in c#

In my current project in work i needed a simple rule engine that processes rules that are saved in the database. In the Database i have the following table:

The column Property stores the name of the property of the overtaken class. The column Operator stores the logical operator which is used to evaluate the rule and the column Value stores the constant to evaluate against. To try this rules we have the Person class.

    public class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public int Children { get; set; }
    }

This class has the properties Name, Age and Children. The rule class stores the rules that are defiened in the database table.

    public class Rule
    {
        private bool propertySet = false;
        public string PropertyName { get; set; }
        public Operator Operator_ { get; set; }
        public object Value { get; set; }

        public Rule(Operator operator_, object value)
        {
            this.Operator_ = operator_;
            this.Value = value;
        }

        public Rule(string propertyName, Operator operator_, object value)
        {
            this.Operator_ = operator_;
            this.Value = value;
            this.PropertyName = propertyName;
            if(!string.IsNullOrEmpty(propertyName))
                this.propertySet = true;
        }
    }

The RuleLoader class loads the rules from the database and stores it in Rule objects. This is the code to load the rules from the database.

            RuleLoader ruleLoader = new RuleLoader();
            Rule firstRule = ruleLoader.Load(1);
            Rule secondRule = ruleLoader.Load(2);
            Rule thirdRule = ruleLoader.Load(3);

Now we have the rules and what we need is a Person to apply the rules to.

Person person = new Person() { Name = "Mathias", Age = 35, Children = 2 };

Now we will define the rule engine that evaluates the values of the property of the Person objects against the definied rules from the database. To do so we need some reflection and some objects from the System.Linq.Expressions namespace. This is the RuleEngine class that generates a Func that we use to evaluate the overtaken rule.

    public class RuleEngine
    {
        public Func<T, bool> CompileRule<T>(Rule rule)
        {
            if (string.IsNullOrEmpty(rule.PropertyName))
            {
                ExpressionBuilder expressionBuilder = new ExpressionBuilder();
                var param = Expression.Parameter(typeof(T));
                Expression expression = 
                    expressionBuilder.BuildExpression<T>(rule.Operator_, rule.Value, param);
                Func<T, bool> func = 
                    Expression.Lambda<Func<T, bool>>(expression, param).Compile();
                return func;
            }
            else
            {
                ExpressionBuilder expressionBuilder = new ExpressionBuilder();
                var param = Expression.Parameter(typeof(T));
                Expression expression = 
                    expressionBuilder.BuildExpression<T>(
                    rule.PropertyName, rule.Operator_, rule.Value, param);
                Func<T, bool> func = 
                    Expression.Lambda<Func<T, bool>>(expression, param).Compile();
                return func;
            }
        }
    }

The RuleEngine class uses the ExpressionBuilder class to build the Expression and compiles it to a lambda expression. This lambda expression does the actual work when a rule is evaluated.

    public class ExpressionBuilder
    {
        public Expression BuildExpression<T>(
            Operator ruleOperator, object value, ParameterExpression parameterExpression)
        {
            ExpressionType expressionType = new ExpressionType();
            var leftOperand = parameterExpression;
            var rightOperand = 
                Expression.Constant(Convert.ChangeType(value, typeof(T)));
            var expressionTypeValue = 
                (ExpressionType)expressionType.GetType().GetField(
                Enum.GetName(typeof(Operator), ruleOperator)).GetValue(ruleOperator);
            var binaryExpression = 
                Expression.MakeBinary(expressionTypeValue, leftOperand, rightOperand);
            return binaryExpression;
        }

        public Expression BuildExpression<T>(
            string propertyName, Operator ruleOperator, object value, 
            ParameterExpression parameterExpression)
        {
            ExpressionType expressionType = new ExpressionType();
            var leftOperand = MemberExpression.Property(parameterExpression, propertyName);
            var rightOperand = Expression.Constant(Convert.ChangeType(value, value.GetType()));
            FieldInfo fieldInfo = 
                expressionType.GetType().GetField(Enum.GetName(typeof(Operator), ruleOperator));
            var expressionTypeValue = (ExpressionType)fieldInfo.GetValue(ruleOperator);
            var binaryExpression = 
                Expression.MakeBinary(expressionTypeValue, leftOperand, rightOperand);
            return binaryExpression;
        }
    }

Here we see the usage of the RuleEngine class. We call the CompileResult method and get back a Func that evaluates us the overtaken parameter (in this case of type Person).

     RuleEngine ruleEngine = new RuleEngine();
     var firstRuleFunc = ruleEngine.CompileRule<Person>(firstRule);
     var secondRuleFunc = ruleEngine.CompileRule<Person>(secondRule);
     var thirdRuleFunc = ruleEngine.CompileRule<Person>(thirdRule);
     var result = firstRuleFunc(person) &&
         secondRuleFunc(person) && thirdRuleFunc(person);

So we know that the Person object

( Person person = new Person() { Name = "Mathias", Age = 35, Children = 2 }; )

passes all the defiend rules from the database.

In the second part of this post i will extend the rule engine to handle collections:
Building a rule engine in c# (part 2: extending the rule engine to handle collections) In this third part of the post series called Building a rule engine in c# (part 3: extending the rule engine to handle aggregations of collections) i extend the rule engine to handle aggregation for collections. 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.

Advertisements

36 Comments on “Building a rule engine in c#”

  1. Lindsay says:

    Hello netmatze,

    I’ve implemented the above code, but I keep getting an error “The value passed in must be an enum base or an underlying type for an enum, such as an Int32. Parameter name: value”. I’ve notice on you Rule object class you have a data type “Operator”. In which namespace is the available? I look forward to you response.

    • netmatze says:

      Hello Lindsay,

      As this is the first comment i ever got at my blog i will give my best to answer your question.
      The Operator is an enumeration that represents the operation saved in the database:

      public enum Operator
      {
      Equal,
      NotEqual,
      GreaterThan,
      LessThan,
      GreaterThanOrEqual,
      LessThanOrEqual
      }

      So you need to convert the string stored in the Database to this enumeration:

      var op = (Operator) Enum.Parse(typeof(Operator), “NotEqual”);

      and then overtake the Operator enumeration to the Rule class.

      Rule firstRule = new Rule(“Name”, op, “test”);

      after that we can combile the rule:

      RuleEngine ruleEngine = new RuleEngine();

      var firstRuleFunc = ruleEngine.CompileRule(firstRule);

      and check if the rule is passed

      var result = firstRuleFunc(person);

      So i hope this helps.

      • Chris Lane says:

        I downloaded the latest version of your code from codeplex and and I am trying to understand it still and I am still reading your articles. I am wondering why you created the Operator Enumeration instead of just using the ExpressionType Enumeration directly? I do see that Operator Enumeration names are the same as some of the values in the ExpressionType Enumeration and they do get converted to ExpressionType in BuildExpression.
        Would I have to add other enumerations to the Operator Enumeration for calculations, like Add, divide etc… ? Does having the Operator Enumeration make it easier to create a UI for users to create rules, if I were to build a UI for rule creation? Sorry if my questions are dumb still trying to understand all this. Rules Engine is a complex topic.

        One other thing when have list of rules, is it possible to know which rule failed?

  2. here is you second commant
    Great code thanks

  3. jim tollan says:

    Hey netmatze,

    Really nice article here and fits perfectly with a project that I’m working on right now. However, the project is part of a larger body of work that is being carried out in .Net v 4.0 (can’t change the target to 4.5 alas!!). Is there an easy way to port this code down to v 4.0?? or are the 4.5 features an absolute requirement for the expressionbuilder class etc.

    I thought I’d struck gold here (in a way I did, as I love the code) but am unfortunately unable to use this unless a v4.0 workaround is possible. Hope you can help as this would be such an advance on the technique that we were considering for our own rules engine (basically embedded rules classes within the pocos -yuck!!)

    cheers for now
    jim

    • jim tollan says:

      Sorry – to clarify, was meaning the use of the Operator class!! Just realised that I didn’t allude to that fact.

      jim

      • netmatze says:

        Hey Jim

        I have implemented this with the .net framework 4.0 and used no 4.5 features.
        If you tell me where you have the troubles to implement this
        in a .net 4.0 project i maybe could help you.

        netmatze

  4. jim tollan says:

    Hey netmatze,

    My misunderstanding, just noticed that I was rushing in too much, now have the code compiling correctly after adding the enum – doh!! Out of interest, have you expanded upon this in recent times at all, or in your usage, is it still pretty much as above??

    Sorry to clog your comments section, feel free to delete mine after this comment 🙂
    jim

    • netmatze says:

      Hey Jim

      I have implemented this some times ago and it still works the same way, i have not extended it.
      My comment section is not so crowded so i need not delete your comments.

      Greetings
      netmatze

  5. Dan says:

    How would one handle situations where you want to write a rule against a property on a child collection? For instance… Consider a Person object with multiple Address objects – what if you wanted to write a rule to make sure there is at least one address with an active status on a person?

    • netmatze says:

      Hello Dan,

      If you want to apply some Rule against a child collection i would do that the following way:
      Lets say we have a Person Object and that Person Object has a list of Adress Objects.

      public class Person
      {
      public string Name { get; set; }
      public int Age { get; set; }
      public int Children { get; set; }
      private List adresses = new List();
      public List Adresses_ { get { return adresses; } set { adresses = value; } }
      }

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

      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 person = new Person() { Name = “Mathias”, Age = 35, Children = 2 };
      person.Adresses_.Add(adresseOne);
      person.Adresses_.Add(adresseTwo);
      person.Adresses_.Add(adresseThree);

      We want to apply to rules against that list ob Adress Objects. The two rules are:

      City – Equals – New York
      ActiveState – Equals – true

      To do so we first have to load the two rules from the database.

      Rule firstAdressRule = ruleLoader.Load(4);
      Rule secondAdressRule = ruleLoader.Load(5);

      Then we have to complile the rules.

      var firstAdressRuleFunc = ruleEngine.CompileRule(firstAdressRule);
      var secondAdressRuleFunc = ruleEngine.CompileRule(secondAdressRule);

      After that we need a method that checks a rule against a collection of Objects. I added that method to the RuleValidator class.

      public bool ValidateValuesAny(List values, Func rule)
      {
      foreach (var value in values)
      {
      if (rule(value))
      {
      return true;
      }
      }
      return false;
      }

      With that method we can do the following.

      RuleValidator ruleValidator = new RuleValidator();
      bool result = ruleValidator.ValidateValuesAny(person.Adresses_, firstAdressRuleFunc);
      result = ruleValidator.ValidateValuesAny(person.Adresses_, secondAdressRuleFunc);

      Now we know if any of the Adress Objects in the Person Object has a City New York and a ActiveState that is true.

  6. Lindsay says:

    Hello netmatze,

    It’s been some time now since my last comment and your response because since then I lost the prototype code which I was working on. I implemented the above code but used a different object class with data types such as float, decimal or double.
    When I build the rule EG. var rule = new Rule(“Holding”, “GreaterThan”, 0); I get the following execution error “The binary operator GreaterThan is not defined for the types ‘System.Single’ and ‘System.Int32’.” or The binary operator GreaterThan is not defined for the types ‘System.Decimal and ‘System.Double” or vice versa. Why is this happening? Why when I define the rule as the following var rule = new Rule(“Holding”, “GreaterThan”, 0.0) the code works. I’m puzzled. I look forward to your response. Great second article as well. Thanks

    • netmatze says:

      Hello Lindsay,

      I tried out your example and i get the same error. The problem is that in the class Rule the value is defined as object. That means if you define the rule
      var rule = new Rule(“Holding”, “GreaterThan”, 0); the type of the value is implicitly System.Int32, if you define it this was var rule = new Rule(“Holding”, “GreaterThan”, 0.0); then the type of the value is System.Double. In the class ExpressionBuilder the method BuildExpression is defined the following:

      public Expression BuildExpression(string propertyName, Operator ruleOperator, object value, ParameterExpression parameterExpression)
      {
      ExpressionType expressionType = new ExpressionType();
      var leftOperand = MemberExpression.Property(parameterExpression, propertyName);
      var rightOperand = Expression.Constant(Convert.ChangeType(value, value.GetType()));
      FieldInfo fieldInfo = expressionType.GetType().GetField(Enum.GetName(typeof(Operator), ruleOperator));
      var expressionTypeValue = (ExpressionType)fieldInfo.GetValue(ruleOperator);
      var binaryExpression = Expression.MakeBinary(expressionTypeValue, leftOperand, rightOperand);
      return binaryExpression;
      }

      When you define the rule: var rule = new Rule(“Holding”, “GreaterThan”, 0); and then you call the Expression.MakeBinary(expressionTypeValue, leftOperand, rightOperand); method. Here we have the problem, it raises the following InvalidOperationException: “The binary operator GreaterThan is not defined for the types ‘System.Double’ and ‘System.Int32′.”.
      That happens because the Expression.MakeBinary does only work for the completely same types. To solve that problem you need to change the BuildExpression method so that it performs a cast of the rightOperator to the type of the left if it is necessary. Here is the code to do so:

      public Expression BuildExpression(string propertyName, Operator ruleOperator, object value, ParameterExpression parameterExpression)
      {
      ExpressionType expressionType = new ExpressionType();
      var leftOperand = MemberExpression.Property(parameterExpression, propertyName);
      var rightOperand = Expression.Constant(Convert.ChangeType(value, value.GetType()));
      FieldInfo fieldInfo = expressionType.GetType().GetField(Enum.GetName(typeof(Operator), ruleOperator));
      var expressionTypeValue = (ExpressionType)fieldInfo.GetValue(ruleOperator);
      return CastBuildExpression(expressionTypeValue, value, leftOperand, rightOperand);
      }

      private Expression CastBuildExpression(ExpressionType expressionTypeValue, object value, Expression leftOperand, ConstantExpression rightOperand)
      {
      if (leftOperand.Type == rightOperand.Type)
      {
      return Expression.MakeBinary(expressionTypeValue, leftOperand, rightOperand);
      }
      else if (CanChangeType(value, leftOperand.Type))
      {
      rightOperand = Expression.Constant(Convert.ChangeType(value, leftOperand.Type));
      return Expression.MakeBinary(expressionTypeValue, leftOperand, rightOperand);
      }
      return null;
      }

      private bool CanChangeType(object sourceType, Type targetType)
      {
      try
      {
      Convert.ChangeType(sourceType, targetType);
      return true;
      }
      catch (Exception ex)
      {
      return false;
      }
      }

      That code checks if the type of the leftOperand and the rightOperand are the same and if they are not it tries to cast the rightOperand to the type of the leftOperand.
      I hope that solves your problem.

  7. Carlos says:

    Great!

    I’ve got a question:

    Is it possible to know exactly which properties does not meet the requirements of the rule?

    For example:

    var listPersons = new List();

    and then for example:

    var listErrorsRulesPersons = listPersons[0].ListErrorsList;

    listErrorsRulesPersons[0].Name = GreatherThan
    listErrorsRulesPersons[0].Children = NotEqual

    Regards,
    CM

    • netmatze says:

      Hello Carlos,

      If you want to accomplish the task to know the property the Rule failed you have to change the RuleEngine code a little bit.
      You have to bring the property name in the return value of the method:

      public Func<T, Tuple[bool, string] > CompileRulePropertyName(Rule rule)
      {
      if (string.IsNullOrEmpty(rule.PropertyName))
      {
      ExpressionBuilder expressionBuilder = new ExpressionBuilder();
      var param = Expression.Parameter(typeof(T));
      Expression expression = expressionBuilder.BuildExpression(rule.Operator_, rule.Value, param);
      Func func = Expression.Lambda<Func>(expression, param).Compile();
      Func<T, Tuple[bool, string]> propertyNameFunc = new Func<T, Tuple>(t =>
      {
      var result = func(t);
      return new Tuple(result, rule.PropertyName);
      });
      return propertyNameFunc;
      }
      else
      {
      ExpressionBuilder expressionBuilder = new ExpressionBuilder();
      var param = Expression.Parameter(typeof(T));
      Expression expression = expressionBuilder.BuildExpression(rule.PropertyName, rule.Operator_, rule.Value, param);
      Func func = Expression.Lambda<Func>(expression, param).Compile();
      Func<T, Tuple[bool, string]> propertyNameFunc = new Func<T, Tuple>(t =>
      {
      var result = func(t);
      return new Tuple(result, rule.PropertyName);
      });
      return propertyNameFunc;
      }
      }

      If you use that method instead of the CompileRule method you have the property in the result value and you can use it liek i did in the following example:

      Person person = new Person() { Name = “Mathias”, Age = 36, Children = 2, Married = true };
      RuleLoader ruleLoader = new RuleLoader();
      Rule firstRule = ruleLoader.Load(1);
      Rule thirdRule = ruleLoader.Load(3);
      RuleEngine ruleEngine = new RuleEngine();
      var firstRuleFunc = ruleEngine.CompileRulePropertyName(firstRule);
      var thirdRuleFunc = ruleEngine.CompileRulePropertyName(thirdRule);
      Tuple[bool, string] firstResultTuple = firstRuleFunc(person);
      if(!firstResultTuple.Item1)
      {
      Console.WriteLine(“firstRule failed with property {0}”, firstResultTuple.Item2);
      }
      Tuple[bool, string] thirdResultTuple = thirdRuleFunc(person);
      if (!thirdResultTuple.Item1)
      {
      Console.WriteLine(“thirdRule failed with property {0}”, thirdResultTuple.Item2);
      }

      I hope i understood your problem and this solution works for you.

      Regards,
      netmatze

      • Carlos says:

        Awesome!!!

        This solution works perfectly for me!!!!

        Many thanks and thanks for help me!!!!!

        Regards,
        CM

  8. Peter says:

    Hi netmatze,
    I am trying to use this rule evaluator, but I can’t find the RuleLoader, could you provide me with that class please?
    Thanks.
    Peter

    • netmatze says:

      Hello Peter,

      If you download the source code from ruleengine.codeplex.com you can see that the RuleLoader class is just a stub class.

      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;
      }
      }
      }

      That means i implemented it to get Rule classes to show how the rule engine works. If you want to use the rule engine in your project then you have to implement your own RuleLoader that loads the properties from your database and builds the rule objects. That would look something like the following:

      // Loading dataTable with values from Database
      var property = dataTable.Rows[0].Field(“Property”);
      var operatorString = dataTable.Rows[0].Field(“Operator”);
      var operator = Enum.Parse(typeof(Operator), operatorString);
      var value = dataTable.Rows[0].Field(“Value”);
      return new Rule(property, operator, value);

      I hope that helps you to solve your problem.

  9. Is this rules engine using the Rete Alogrithm please? if not what type of Algorithm it is using? thanks 🙂

    • netmatze says:

      Hello Francesco,

      The rule engine does not use the rete algorithm. It works much simpler with expression trees and with a stack based evalutation engine.

      greetings
      netmatze

  10. Javier says:

    Hi netmatze. Would it be possible to realize a comparison of elements that finds in a list? For example:

    var address = new Adresse { City =”Seville”};
    string text = ” Address.City in (‘Seville’,’London’) “;
    Person person = new Person() { Name = “mathias”, Age = 36, Children = 2, Married = true, Address=address};
    ExpressionEvaluatorLexer expressionEvaluatorLexer = new ExpressionEvaluatorLexer(text, 1);

    I have a property of an object which value contains several elements separated by the character ‘,’ and I need to compared in a expression:

    If person.Address.City contains ‘Seville’ or ‘London’-> expression is true.

    Or it might express:

    var address = new Adresse { City =”Seville”};
    string text = ” Address.City in (‘Seville’,’London’) “;

    Thanks.

  11. srinivas says:

    Hi netmatze,

    Below delegate function expecting second parameter , does it mean we need to pass the ref value so that it will return the result. Please confirm once?
    firstRuleFunc(person)

    • netmatze says:

      Hello sriniva,

      I am not sure what you mean by passing the second parameter as ref value.
      If you need to validate a rule against an object you can make it the following way:
      var rule = new Rule(“Age”, Operator.LessThanOrEqual, 50);
      Person person = new Person() { Name = “Mathias”, Age = 36, Children = 2, Married = true };
      RuleEngine.RuleEngine ruleEngine = new RuleEngine.RuleEngine();
      var ruleFunc = ruleEngine.CompileRule(rule);
      var result = ruleFunc(person);
      Assert.AreEqual(result, true);

      greetings
      netmatze

  12. Hello!

    Thank you for your articles.

    Could you give an example of the rule when PropertyName is empty ?

  13. Scott Morrison says:

    Is it possible to evaluate expression that do NOT evaluate to true/false? For example:
    21 * (64 / 4 + (13 * 2))

    How would this be accomplished? Great work, BTW.

    • netmatze says:

      Hello Scott,

      I am sorry it took so long to answer your question but i was ill and could not implement the solution you need. Now i did it and i checked it in and wrote the test case SimpleExpressionEvaluateNonBoolean.
      It looks the following way:
      [TestMethod]
      public void SimpleExpressionEvaluateNonBoolean()
      {
      EventPerson person1 = new EventPerson()
      {
      Name = “Mathias”,
      ColorComplexion = 5,
      Height = 10,
      Event = “Wedding”
      };
      Evaluator evaluator = new Evaluator();
      var result = evaluator.EvaluateNonBoolean(
      ” 21 * (64 / 4 + (13 * 2)) “, person1); //,’Beautiful Dress’
      Assert.AreEqual(result, 882);
      }

      I hope that helps. Greetings netmatze

      • Scott Morrison says:

        Awesome work, as always and I appreciate the response. Question though: Why does “EvaluateNonBoolean” require a Person object at all? In your test it does not appear to be used…unless I am confused. Can the string be evaluated without the need for the object?

      • netmatze says:

        Hello Scott, you are totally right it would be much better to remove the Object parameter from the EvaluateNonBoolean method.

  14. Scott Morrison says:

    Sir,

    Sorry to be a bother, but your latest build (July 4th) has broken calling methods within expressions. For example: I cannot get ” if (10 < 12) then SetValue(12) else SetValue(1) " to work at all, while it worked fine with previous versions. Let me know if you need more information and thanks again.

    • netmatze says:

      Can you please send me your whole test case.

      • Scott Morrison says:

        Here’s the complete Test Case:

        [TestMethod]
        public void ScottTest()
        {
        Person person1 = new Person()
        {
        Name = “Mathias”,
        Age = 36,
        Children = 2,
        Married = true,
        Birthdate = new DateTime(1976, 5, 9)
        };
        Person person2 = new Person()
        {
        Name = “Anna”,
        Age = 32,
        Children = 2,
        Married = false,
        Birthdate = new DateTime(2002, 2, 2)
        };
        Evaluator evaluator = new Evaluator();
        var result1 = evaluator.Evaluate(
        ” if (10 < 12) then SetCanReceiveBenefits(true) else SetCancelBenefits(true) ", person1);
        Assert.AreEqual(result1, true);
        Assert.AreEqual(person1.CancelBenefits, false);
        Assert.AreEqual(person1.ReceiveBenefits, true);
        var result2 = evaluator.Evaluate(
        ” (Age > 10) then SetCanReceiveBenefits(true) else SetCancelBenefits(true) “, person2);
        Assert.AreEqual(result2, true);
        Assert.AreEqual(person2.CancelBenefits, false);
        Assert.AreEqual(person2.ReceiveBenefits, true);
        }

        — It seems that if you include the word “if” in the statement, everything fails….whereas this was simply ignored in past releases. Hope this helps.

        Also…if you have an Overloaded method such As: SetCancelBenefits(bool) and SetCancelBenefits(string), it will also fail. I have fixed this…let me know if you would like the code to do so. It’s a simple 1-line change..

      • netmatze says:

        Could you make the changes and check them in.

        Thanks
        netmatze


If you have a note or a question please write a comment.

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s