fluentvalidation - Multiple partial validations -
the system i'm developing uses fluentvalidation (v5.0.0.1).
what want create several validators partially validate object, can combine in other validators depending on required @ time.
for example, class has name , address. (this can't split separate class in examples).
for scenario 1, want validate name only, write name validator class.
for scenario 2, want validate address, write address validator class.
for scenario 3, want validate both name , address, want write new validator class calls name validator , address validator.
i don't want repeat code in different places, why want them separate. don't want use when operator there no way determine when contents of object.
i know can call setvalidator, how write call?
rulefor(j=>j).setvalidator(new namevalidator()); rulefor(j=>j).setvalidator(new addressvalidator());
doesn't work.
i explain solution example. i'am going validate contact entity:
public class contact { public string firstname { get; set; } public string lastname { get; set; } public string address1 { get; set; } public string address2 { get; set; } public string city { get; set; } public string postalcode { get; set; } }
the requirement validate firstname , lastname address1, address2, city, postalcode , have posibility reuse our validators in other entities.
create interfaces define specific entity is.
public interface iamperson { string firstname { get; set; } string lastname { get; set; } } public interface ihaveaddress { string address1 { get; set; } string address2 { get; set; } string city { get; set; } string postalcode { get; set; } }
now contact entity has implement both interfaces:
public class contact : iamperson, ihaveaddress { public string firstname { get; set; } public string lastname { get; set; } public string address1 { get; set; } public string address2 { get; set; } public string city { get; set; } public string postalcode { get; set; } }
then, create first validator iamperson entity
public class personvalidator : abstractvalidator<iamperson> { public personvalidator() { rulefor(data => data.firstname).length(3, 50).withmessage("invalid firstname"); rulefor(data => data.lastname).length(3, 50).withmessage("invalid lastname"); } }
the second 1 ihaveaddress entity
public class addressvalidator : abstractvalidator<ihaveaddress> { public addressvalidator() { rulefor(data => data.address1).notnull().notempty().withmessage("invalid address1"); rulefor(data => data.address2).notnull().notempty().withmessage("invalid address2"); rulefor(data => data.city).notnull().notempty().withmessage("invalid city"); rulefor(data => data.postalcode).notnull().notempty().withmessage("invalid postalcode"); } }
way use custom validators
public class contactvalidator: abstractvalidator<contact> { public contactvalidator() { rulefor(contact => contact).setvalidator(new personvalidator()); rulefor(contact => contact).setvalidator(new addressvalidator()); } }
now can use validators validate person data or address data in other entity. unique thing have implement specific interfaces in entities going validate.
[update]
you can increase readability of code adding extension methods
public static class validatorextensions { public static irulebuilderoptions<t, ihaveaddress> musthaveavalidaddress<t>(this irulebuilder<t, ihaveaddress> rulebuilder) { return rulebuilder.setvalidator(new addressvalidator()); } public static irulebuilderoptions<t, iamperson> mustbeavalidperson<t>(this irulebuilder<t, iamperson> rulebuilder) { return rulebuilder.setvalidator(new personvalidator()); } }
this final result using extension methods have added:
rulefor(contact => contact).mustbeavalidperson(); rulefor(contact => contact).musthaveavalidaddress();
Comments
Post a Comment