public EvaluatedRule GenerateEvaluatedRule <TConcrete>(BaseRuleAttribute attribute, PropertyInfo targetProp) { var regexAttr = attribute as RegexRuleAttribute; var input = Expression.Parameter(typeof(TConcrete), "i"); var ctor = typeof(Regex).GetConstructors().SingleOrDefault(c => c.GetParameters().Count() == 1); var method = typeof(Regex).GetMethods() .SingleOrDefault(m => m.Name == "IsMatch" && !m.IsStatic && m.GetParameters().Count() == 1); var leftExpr = Expression.PropertyOrField(input, targetProp.Name); var block = Expression.Block( Expression.Call( Expression.New( ctor, Expression.Constant(regexAttr.RegularExpression)), method, leftExpr) ); var expression = Expression.Lambda(block, input); return(new EvaluatedRule { RuleType = RuleType.Error, MessageFormat = string.Format("{0} does not match the expected format", targetProp.Name.AddSpaces(), regexAttr.RegularExpression), Expression = expression }); }
public static EvaluatedRule ProcessRule <TConcrete>(this Dictionary <Type, IHandler> handlerMapping, BaseRuleAttribute attribute, PropertyInfo targetProp) { var handler = handlerMapping.FindHandler(attribute); return(handler.GenerateEvaluatedRule <TConcrete>(attribute, targetProp)); }
public EvaluatedRule GenerateEvaluatedRule <TConcrete>(BaseRuleAttribute attribute, PropertyInfo targetProp) { var expressions = new List <Expression>(); var messages = new List <string>(); var relationalAttr = attribute as RelationalOperatorAttribute; var srcType = typeof(TConcrete); var input = Expression.Parameter(srcType, "i"); var leftExpr = Expression.PropertyOrField(input, targetProp.Name); var isNullable = targetProp.IsNullable(); if (relationalAttr.CanBeNull) { if (isNullable) { var nullConstant = leftExpr.CreateBinaryExpression(targetProp); expressions.Add(nullConstant); messages.Add("It can also be null."); } else { throw new NotNullablePropertyException(targetProp.Name); } } if (relationalAttr.ConstantValue != null) { var constantValue = Expression.Constant(relationalAttr.ConstantValue); BinaryExpression finalExpr = leftExpr.CreateBinaryExpression(constantValue, relationalAttr.SupportedType, targetProp); expressions.Add(finalExpr); messages.Add(string.Format("Or {0} can be {1} {2}.", targetProp.Name.AddSpaces(), relationalAttr.SupportedType.ToString().AddSpaces(), relationalAttr.ConstantValue)); } if (!string.IsNullOrEmpty(relationalAttr.OtherPropertyName)) { var otherPropInfo = srcType.GetProperty(relationalAttr.OtherPropertyName); var rightExpr = Expression.PropertyOrField(input, relationalAttr.OtherPropertyName); var propExpr = leftExpr.CreateBinaryExpression(rightExpr, relationalAttr.SupportedType, targetProp, otherPropInfo); expressions.Add(propExpr); messages.Add(string.Format("{0} should be {1} the {2}.", targetProp.Name.AddSpaces(), relationalAttr.SupportedType.ToString().AddSpaces(), relationalAttr.OtherPropertyName.AddSpaces())); } var orExpr = expressions.CreateBinaryExpression(); var lambdaExpr = Expression.Lambda(orExpr, input); messages.Reverse(); return(new EvaluatedRule { MessageFormat = string.Join(" ", messages), Expression = lambdaExpr, RuleType = relationalAttr.RuleType }); }
public EvaluatedRule GenerateEvaluatedRule <TConcrete>(BaseRuleAttribute attribute, PropertyInfo targetProp) { var rangeAttr = attribute as RangeRuleAttribute; var input = Expression.Parameter(typeof(TConcrete), "a"); var propName = targetProp.Name; var comparison = Expression.And( Expression.GreaterThan(Expression.PropertyOrField(input, propName), Expression.Constant(rangeAttr.MinValue)), Expression.LessThan(Expression.PropertyOrField(input, propName), Expression.Constant(rangeAttr.MaxValue)) ); var lambda = Expression.Lambda(comparison, input); return(new EvaluatedRule { MessageFormat = string.Format("{0} should be between {1} and {2}", propName.AddSpaces(), rangeAttr.MinValue, rangeAttr.MaxValue), RuleType = RuleType.Error, Expression = lambda }); }
public bool Handles(BaseRuleAttribute attribute) { return(typeof(RangeRuleAttribute).IsAssignableFrom(attribute.GetType())); }
public bool Handles(BaseRuleAttribute attribute) { return(typeof(RelationalOperatorAttribute).IsAssignableFrom(attribute.GetType())); }
public static IHandler FindHandler(this Dictionary <Type, IHandler> handlerMapping, BaseRuleAttribute attribute) { var handler = handlerMapping.Values.SingleOrDefault(h => h.Handles(attribute)); if (handler == null) { var attrType = attribute.GetType(); throw new HandlerNotFoundException(attrType.Name, attrType.FullName); } return(handler); }
public static bool Is <T>(this BaseRuleAttribute attribute) where T : BaseRuleAttribute { return(attribute != null && attribute is T); }