Validation Everywhere V.0.1.0.0
I could repeat the same words from my last post but I´ll say it different this time: Today I released yet another CodePlex project. I´m coordinator on 5 already: Bhal, Wom, TFSVTree Browser, NMVP and now Validation Everywhere.
Validation Everywhere had it´s first release TODAY! You can check out Release 0.1.0.0 here!
The Validation Everywhere project was born because I have a very complex UI that I need to unit test. This UI is built using MVP Architecture (Powered by NMVP), but in ASP.Net it has a lot of Validators logic to perform UI Validation. Since this logic is extremely complex I need to unit test it.
But how to do it if it´s performed by ASP.Net? Surely I could mock every single ASP.Net Validator, but that would become a very cumbersome job since when I update the ASP.Net I´d have to update the Unit tests (and if I have a Windows Forms in the future, I´d have to update that too).
So I decided to write Validation Everywhere.
It´s focus is to build an Extensible, Declarative Validation Framework.
Let´s explain those two pretty words: Extensible and Declarative.
Validation Everywhere is extensible because it has an IValidator Interface and a concrete implementation of it (BaseValidator) from which you can create your own validators. This allows you to extend the framework in any way you see fit.
It´s also declarative, since the validation rules for your code is in an XML File and can be changed without recompiling tha application.
Now I know all you people want is to see some code, so here it comes:
1: public void DoMyValidation(){ 2: //Creates the Mocks to be validated.
3: ValidationObjectMock mock = new ValidationObjectMock();
4:
5: //Configures the mock.
6: mock.DateProperty = DateTime.Now;
7: mock.DateProperty2 = DateTime.Now;
8: mock.IntProperty = 10;
9: mock.IntProperty2 = 10;
10: mock.DoubleProperty = 50.4023;
11: mock.DoubleProperty2 = 50.4023;
12: mock.StringProperty = "heynemann@gmail.com";
13: mock.StringProperty2 = "heynemann@gmail.com";
14: mock.Time = new TimeSpan(10, 0, 0);
15:
16: //Creates a new Validation Context.
17: ValidationContext ctx = new ValidationContext();
18:
19: //Adds a Validation Context Required property.
20: ctx.AddRequired("DateProperty", "The date property must be filled."); 21:
22: //Adds two Compare Validators.
23: ctx.AddCompare("DateProperty", "DateProperty2", DataType.Date, 24: Operators.Equal, "Date Properties are different.");
25: ctx.AddCompareByValue("IntProperty", 10, DataType.Integer, 26: Operators.Equal, "Int and Value are different.");
27:
28: //Adds a Custom Validator
29: ctx.AddCustom("Time", HandleValidateTimeSpan, "The time property must be filled."); 30:
31: //Adds a Ranged Validator
32: ctx.AddRanged("DateProperty", new DateTime(2000, 1, 1), new DateTime(2006, 12, 31), 33: "The DateTime Property isn´t in the specified range.");
34:
35: //Adds a Regular Expression Validator
36: string emailPattern =
37: "^[a-zA-Z][\\w\\.-]*[a-zA-Z0-9]@[a-zA-Z0-9][\\w\\.-]
*[a-zA-Z0-9]\\.[a-zA-Z][a-zA-Z\\.]*[a-zA-Z]$";
38: ctx.AddRegExpression("StringProperty", emailPattern, 39: "The String Property isn´t an e-mail.");
40:
41: //Performs Validation
42: bool isValid = ctx.Validate(mock);
43:
44: //If any Errors occured they are in the Error Messages collection.
45: int i = 0;
46: foreach (string str in ctx.ErrorMessages) { 47: Console.WriteLine("Error #{0} - {1}", (++i).ToString(), str); 48: }
49: }
50:
51: private void HandleValidateTimeSpan(object sender, CustomValidatorValidateEventArgs e) { 52: if (e.TypeToValidate != typeof(TimeSpan)) { 53: throw new InvalidOperationException();
54: }
55: e.IsValid = (((TimeSpan)e.ValueToValidate) > new TimeSpan(5, 0, 0));
56: }
As you see it´s VERY easy to perform validation in ValEver (the code name for Validation Everywhere as you might have noticed :)).
Well, I hope to be hearing a lot of suggestions soon (Please be a nice guy/girl and post in the Validation Everywhere discussion forums).
Bernardo Heynemann

#84