Microsoft is on the verge of releasing version 3.0 of the Enterprise Library. Among the many new features included in version 3.0 is a block called the Validation Application Block (VAB). The VAB is one of my favorite blocks because of its simplicity, extensibility and how relative it is to application development.
"The Enterprise Library Validation Application Block provides a library of classes, called validators, that supplies the code for validating .NET Framework data types. For example, one validator checks for null strings and another validator checks that a number falls within a specified range." - http://www.codeplex.com/entlib
There are three ways to use the VAB. You can place attributes above your methods, use a configuration file to define rule sets or code the validation logic.
Below is an example from the documentation demonstrating the simplicity of the VAB. The MyExample class thows an exception if the length of the CustomerName value is greater than 20 characters using the StringLengthValidator attribute. The use of attributes is straightforward, intuitive and simple.
1: public class Customer
2: { 3: [StringLengthValidator(0, 20)]
4: public string CustomerName;
5:
6: public Customer(string customerName)
7: { 8: this.CustomerName = customerName;
9: }
10: }
11:
12: public class MyExample
13: { 14: public static void Run()
15: { 16: Customer myCustomer = new Customer("A name that is too long"); 17: ValidationResults r = Validation.Validate<Customer>(myCustomer);
18: if (!r.IsValid)
19: { 20: throw new InvalidOperationException("Validation error found."); 21: }
22: }
23: }
There are a number of out of box Validators you can use that cover most scenerios. Here is a list of Validators from the Februrary CTP release:
And Composite Validator
Contains Characters Validator
Date Time Range Validator
Domain Validator<T>
Enum Conversion Validator
Not Null Validator
Object Collection Validator
Object Validator
Or Composite Validator
Property Comparison Validator
Range Validator<T>
Regular Expression Validator
Relative Date Time Validator
String Length Validator
Type Conversion Validator
The VAB documentation includes sample code and quickstarts to get you started.
Custom Validation Example
The VAB is designed as is most of the Enterprise Library on the Open-Closed Principle. In other words, the VAB is easy to extend yet doesn't require modifying the VAB code. http://codebetter.com/blogs/david.hayden/archive/2005/06/04/64095.aspx
In the code below, I created a custom validator called NotEmptyCollectionValidator, which validates that an object collection is not empty. See the code below.
1: [NotEmptyCollectionValidator]
2: public ObligorCollection ObligorCollection
3: { 4: get { return _obligorCollection; } 5: }
Here is the NotEmptyCollectionValidator class and NotEmptyCollectionValidatorAttribute class:
1: using System;
2: using System.Collections;
3: using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
4: using Microsoft.Practices.EnterpriseLibrary.Validation;
5: using Microsoft.Practices.EnterpriseLibrary.Validation.Configuration;
6: using Microsoft.Practices.EnterpriseLibrary.Validation.Validators;
7:
8: namespace Halos.DocumentManagement.VirtualVault.BusinessLibrary
9: { 10: [ConfigurationElementType(typeof (CustomValidatorData))]
11: public class NotEmptyCollectionValidator : Validator
12: { 13: public NotEmptyCollectionValidator() : base(null, null) { } 14:
15: protected override string DefaultMessageTemplate
16: { 17: get { return "The collection {0} does not have any items"; } 18: }
19:
20: protected override void DoValidate(object objectToValidate, object currentTarget, string key, ValidationResults validationResults)
21: { 22: ICollection obCollection = (ObligorCollection) objectToValidate;
23: if (obCollection.Count == 0)
24: { 25: string message = string.Format(MessageTemplate, objectToValidate);
26: LogValidationResult(validationResults, message, currentTarget, key);
27: }
28: }
29: }
30:
31: public class NotEmptyCollectionValidatorAttribute : ValidatorAttribute
32: { 33: protected override Validator DoCreateValidator(Type targetType)
34: { 35: return new NotEmptyCollectionValidator();
36: }
37: }
38: }
As you can see extending the VAB to add custom validators is quite easy.