samedi 3 octobre 2009

xVal - ValidationAspects RulesProvider

Le framework xVal permet de déployer les règles de validation côté serveur vers l'interface web. Il peut utiliser différents frameworks du côté client comme JQuery ou ASP.net. De la même manière il peut s'appuyer sur différents framework de validation pour déduire les règles de validation serveur. Et il s'intègre particulièrement bien à ASP.net MVC !

De son côté ValidationAspects est un framework de validation assez simple d'utilisation.

Ni l'un ni l'autre de ces deux frameworks ne propose d'implémentation les rendant compatibles mais en regardant le source des fournisseurs de règles xVal pour Castle ou NHibernate, on ne met pas bien longtemps à en construire un pour ValidationAspects ... d'ailleur le voici :



using xVal.RuleProviders;
using VA = ValidationAspects;
using xVal.Rules;
using System.Reflection;
using ValidationAspects.Sdk;
using ValidationAspects.Factories;

namespace TestsApp.Validation.xVal
{
public class ValidationAspectsRulesProvider : CachingRulesProvider
{
private readonly RuleEmitterList<ValidatorAttribute> validationRuleEmitters = new RuleEmitterList<ValidatorAttribute>();

public ValidationAspectsRulesProvider()
{
var e = validationRuleEmitters;
e.AddSingle<VA.GreaterThanAttribute>(MakeGreaterThanRule);
e.AddSingle<VA.InRangeAttribute>(MakeInRangeRule);
e.AddMultiple<VA.IsDateAttribute>(x => new Rule[] {
new RequiredRule(),
new DataTypeRule(DataTypeRule.DataType.Date)
});
e.AddSingle<VA.IsEmailAttribute>(x => new DataTypeRule(DataTypeRule.DataType.EmailAddress));
e.AddSingle<VA.LengthInRangeAttribute>(MakeLengthInRangeRule);
e.AddSingle<VA.LessThanAttribute>(MakeLessThanRule);
e.AddSingle<VA.MatchesRegexAttribute>(MakeMatchesRegexRule);
e.AddSingle<VA.MaximumAttribute>(MakeMaximumRule);
e.AddSingle<VA.MaximumLengthAttribute>(MakeMaximumLengthRule);
e.AddSingle<VA.MinimumAttribute>(MakeMinimumRule);
e.AddSingle<VA.MinimumLengthAttribute>(MakeMinimumLengthRule);
e.AddSingle<VA.NotNullAttribute>(x => new RequiredRule());
e.AddSingle<VA.NotNullOrEmptyAttribute>(x => new RequiredRule());
}


protected override RuleSet GetRulesFromTypeCore(Type type)
{
// Rêgles de validation
var rules = from member in type.GetMembers(BindingFlags.Instance | BindingFlags.Public)
// pour les champs et propriétés
where (member.MemberType == MemberTypes.Field || member.MemberType == MemberTypes.Property)
// joints à leurs attributs hérité du framework de validation
from att in GetMemberAttributes(member)
// et joints aux rêgles qui en découle
from rule in ConvertToXValRules(att)
select new { MemberName = member.Name, Rule = rule };
;

return new RuleSet(rules.ToLookup(x => x.MemberName, x => x.Rule));
}

IEnumerable<ValidatorAttribute> GetMemberAttributes(MemberInfo member)
{
return member.GetCustomAttributes(true).Where(att => att is ValidatorAttribute)
.Cast<ValidatorAttribute>();
}

private IEnumerable<Rule> ConvertToXValRules(ValidatorAttribute att)
{
return validationRuleEmitters.EmitRules(att);
}


#region MakeRules

private Rule MakeInRangeRule(VA.InRangeAttribute att)
{
var facto = att.Factory as InRange;
return new RangeRule(Convert.ToDecimal(facto.Minimum), Convert.ToDecimal(facto.Maximum));
}
private Rule MakeGreaterThanRule(VA.GreaterThanAttribute att)
{
var facto = att.Factory as GreaterThan;
return new RangeRule(Convert.ToDecimal(facto.Value), null);
}
private Rule MakeMinimumRule(VA.MinimumAttribute att)
{
var facto = att.Factory as Minimum;
return new RangeRule(Convert.ToDecimal(facto.Value), null);
}
private Rule MakeLessThanRule(VA.LessThanAttribute att)
{
var facto = att.Factory as LessThan;
return new RangeRule(null, Convert.ToDecimal(facto.Value));
}
private Rule MakeMaximumRule(VA.MaximumAttribute att)
{
var facto = att.Factory as Maximum;
return new RangeRule(null, Convert.ToDecimal(facto.Value));
}

private Rule MakeLengthInRangeRule(VA.LengthInRangeAttribute att)
{
var facto = att.Factory as LengthInRange;
return new StringLengthRule(facto.Minimum, facto.Maximum);
}
private Rule MakeMinimumLengthRule(VA.MinimumLengthAttribute att)
{
var facto = att.Factory as MinimumLength;
return new StringLengthRule(facto.Length, null);
}
private Rule MakeMaximumLengthRule(VA.MaximumLengthAttribute att)
{
var facto = att.Factory as MaximumLength;
return new StringLengthRule(null, facto.Length);
}

private Rule MakeMatchesRegexRule(VA.MatchesRegexAttribute att)
{
var facto = att.Factory as MatchesRegex;
return new RegularExpressionRule(facto.Regex);
}

#endregion
}
}



Enjoy !

Aucun commentaire: