It is continuation of first post - << click here to read
and second post - < click here to read
Dynamicity is of great advantage. First of all let us move forward step wise, define delegate to a separate method;
and second post - < click here to read
Dynamicity is of great advantage. First of all let us move forward step wise, define delegate to a separate method;
should tends to
rule.AddCondtion(IsPriceGreaterOrEqualToZero());
public static Predicate<PriceObject> IsPriceGreaterOrEqualToZero()
{
return delegate(PriceObject po) { return po.NetProductPrice >= 0; };
}
Let us consider even more generic function to write. Point is every condition returns Predicate<PriceObject> and internally the condition result is a Boolean variable (true/false). Why not create runtime generic delegate to handle Equals operator for example. We will make it compatible to other operators later.
public static Predicate<T> GetConditiPredicate<T>(string fieldName, string operatorName, string value)
{
Type itemType = typeof(T);
ParameterExpression predParam = Expression.Parameter(itemType, "po");
PropertyInfo propertyInfo = itemType.GetProperty(fieldName);
Expression left = Expression.Property(predParam, propertyInfo);
Expression right = Expression.Constant(ObjTypeConverter.ChangeType(value, propertyInfo.PropertyType), propertyInfo.PropertyType);
Expression equality = Expression.GreaterThanOrEqual(left, right);
Func<T, bool> function = (Func<T, bool>)Expression.Lambda(equality, new[] { predParam }).Compile();
return new Predicate<T>(function);
}
And caller can deliver a call like this
rule.AddCondtion(Dynamic.GetConditiPredicate<PriceObject>("DRM", "Equals", "2"));
Well compile and see if it works fine. It should :)
Now let us replace the statement with more general one….
//Expression equality = Expression.GreaterThanOrEqual(left, right);
Expression result = GetExpression(operatorName, left, right);
Func<T, bool> function = (Func<T, bool>)Expression.Lambda(result, new[] { predParam }).Compile();
And
public static Expression GetExpression(string operatorName, Expression left, Expression right)
{
Expression result = null;
switch (operatorName.ToLower())
{
case "equals":
result = Expression.Equal(left, right);
break;
case "greaterorequal":
result = Expression.GreaterThanOrEqual(left, right);
break;
case "lessorequal":
result = Expression.LessThanOrEqual(left, right);
break;
case "greaterthan":
result = Expression.GreaterThan(left, right);
break;
case "lessthan":
result = Expression.LessThan(left, right);
break;
case "add":
result = Expression.Add(left, right);
break;
case "subtract":
result = Expression.Subtract(left, right);
break;
case "multiply":
result = Expression.Multiply(left, right);
break;
case "divide":
result = Expression.Divide(left, right);
break;
default:
throw new Exception("Unknown Operator Name");
}
return result;
}