One of the Application Blocks planned for a (future) release of Enterprise Library is Validation.

I have been building a quick prototype to get our head around the scenarios it should address and how, and most importantly to expose assumptions and gaps - so then we can go ask folks questions that are actionable. 

So, first things first, here is our quick Enterprise Library Validation Block survey: Tell us what you need!
http://www.zoomerang.com/survey.zgi?p=WEB2QYNLVRL4

With regards to the prototype, so far I'm relatively happy with it. I also tried summarizing the refactorings it went through using patterns:

1) I started with a Specification (Evans) pattern, for an untyped 'target'. 
Although Specification can be used for more than Validation, I thought just to start with this specific use. I called these implementations of specifications Validators. There's a corresponding interface & base class. Essentially it has:

bool Validate(object target)

2) I then separated the Validators from their Factories (GoF). These factories ended up all having a common interface (IValidatorFactory).

3) For sets of validation rules, I then made a Composite (Gof) (or a degenerate composite as kindly termed in Portland's Wiki). This lets me treat collections of Validators as any validator.

4) The validations can express results simply (booleans) or post the results to a ValidationResults collection. While I originally thought of that refactoring as aadding a Blackboard (POSA) reality is that most of the validators will typically just add failed validation results there. So maybe it's just a collector argument.
(somebody stole my POSA book ..#$@! The Siemens guys gave me that copy personally! You know who you are..and I know you are reading this..)

5) I then built a facade (GoF) with some static functions for one-liner access

6) I then thought to add attributes (decorator) that, in turn, are validation factories.

7) Then I built some simple validators and voila! it was going. The core of the block prototype is 3 interfaces, 2 base classes, the ValidationResults and the Facade.

So I decided to use the fact that KZU was around and enticed him to the office by putting a path of cashew nuts leading to it. It was a short path because he's been sitting 3 meters away for some time now. So we decided to build a new XPath expression -based validator.

1) Making a test that fails (2 mins)

Our test was to validate this class:

[XPathValidation("@LargeValue > 7 and (@MinValue < @MaxValue)")]
public class TestClassC
{
  
private int largeValue;
   
private double minValue;
   private double maxValue;


   //properties for fields above

   
public int LargeValue{ ... etc }
   public int MinValue{ ... etc }
   public int MaxValue{ ... etc }

}

The goal was to validate it with this code:

[Test]
public void TestXpath()
{
   
TypeValidatorFactory tf = new TypeValidatorFactory(typeof(TestClassC));
   
ValidatorBase v = tf.CreateValidator();
   

   TestClassC c = new TestClassC();
   
c.LargeValue= 8; //class validation attribute says > 7
   
c.MinValue= 3;
   
c.MaxValue= 7;
   
   
Assert.IsTrue(v.Validate(c));
}

2) Making it pass (15 mins including distractions)

To build this we first got ObjectXPathNavigator from here:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnexxml/html/xml03172003.asp
and moved over the ObjectProxy and ObjectXPathNavigator classes to my project

We then wrote the XPathValidator (simplified but working code below, the other validator function calls this one and if it didn't pass creates a verbose ValidationResult). Note XPathValidator just works on Properties of Classes (not on structs or public fields)

public override bool Validate(object target)
{
   XPathNavigator nav = new ObjectXPathNavigator(target);
   nav.MoveToFirstChild(); //so the class elements are the current elements
   object res = nav.Evaluate(Expression);
   return Convert.ToBoolean(res);
}

Then theXPathValidationAttribute is like this (remember the ValidationAttributes are a factory)

[AttributeUsage(AttributeTargets.Class)]
public class XPathValidationAttribute : ValidationAttribute
{
   
private string expression;

   
public XPathValidationAttribute(string expression)
   {
      t
his.expression = expression;
   
}

   public override ValidatorBase CreateValidator()
   
{
      
return new XPathValidator (expression);
   
}

}

That was it! I really like to be able to add a new validator so easily. We still have a lot to go (e.g. being able to specify part of the validation in config, making specialized validations for more than just .NET types e.g. winforms, other data structures, etc) but for the amount of time invested the result looks promising

Some issues to consider are:

-Perf - I built this so it would be minimum overhead and so that trees of validators could be constructed once and then reused in a thread-safe way. The reflection cost incurred for attribs therefore just happens once.  The facade could help access cached or new validators transparently.

-Perf of complex expressions - Ah... the longing for a metaprogramming helper - something that, like serialization, helped me build classes on the fly, compile them, and keep them around for future use.

- etc etc. Take the survey (link above) and tell us what are the issues we should consider!

Thanks

ps. and thanks David for your deployment scenario - we are floating it internally comparing it with others.!