Error message

  • Notice: Undefined index: text in _geshifilter_geshi_factory() (line 92 of /home/nichesw/public_html/sites/all/modules/geshifilter/geshifilter.inc).
  • Notice: Undefined index: text in _geshifilter_geshi_factory() (line 92 of /home/nichesw/public_html/sites/all/modules/geshifilter/geshifilter.inc).

Easier property validation with dynamic in C# 4

High quality input validation is essential to many, if not all systems that we write. It doesn't matter whether we're validating user input in a WPF or Silverlight application, checking data transfer objects passed into a service layer or verifying the information in a JSON packet submitted by REST, validation is essential.

Lately, I've been working with a bunch of code that looks like this:

var results = new List<ValidationResult>();
 
if (string.IsNullOrWhitespace(myPerson.FullName))
{
    results.Add( 
        new ValidationResult(
            "FullName", "Full Name is a mandatory field"));
}
else if (myPerson.FullName.Length > 100)
{
    results.Add( 
        new ValidationResult(
            "FullName", "Full Name must be 100 characters or less."));
}
 
if (string.IsNullOrWhitespace(myPerson.KnownAs))
{
    results.Add(
        new ValidationResult(
            "KnownAs", "Known As is a mandatory field"));
}
else if (myPerson.KnownAs.Length > 50)
{
    results.Add( 
        new ValidationResult(
            "KnownAs", "Known As must be 50 characters or less."));
}

This code works - but it is ugly. The code is verbose and repetitive - the mechanics of building ValidationResult items and adding them to the results list swamp the actual checks being made.

Inspired in part by an Ivan Towlson presentation at Microsoft TechEd 2011 in New Zealand, I've got a prototype going in Visual Studio 2010 that looks like this:

var results = new List<ValidationResult>();
using (dynamic check = new ValidationContext(myPerson, results))
{
    check.FullName( mandatory: true, maxlength: 100);
    check.KnownAs( mandatory: true, maxlength: 50);
}

How on earth does this work?

  • The ValidationContext class provides an ambient context for validation that gathers up validation results in the background, without any need to pass around the list itself.
  • Leveraging the new dynamic keyword in C# 4 allows the ValidationContext to behave as though it has a method for each property declared on myPerson. The named parameters passed to these dynamic methods specify the requested checks.

What do you think? Does this qualify as evil code, or merely expressive?

Should I turn this prototype into an actual library and make it available for download?

Update: Ivan Towlson has responded with a blog entry of his own: Dynamic interfaces in C#

Blog Tags: 

Comments

This can have very well defined behavior so I don't think it's evil at all.

You have some special sue case that requires you to reinvent that wheel? There are several wheels around - http://fluentvalidation.codeplex.com/ just to name one... or are you just prototyping for it's own sake?

Do I need a special use case, SaltySeaDog?

In many ways this post is a thought experiment. Playing around with new language features and libraries leads to new, and possibly better, ways of doing things.

To illustrate, note that the Fluent validation library you linked is dependent on both method chaining and use of lamda expressions to identify properties by name. While method chaining was possible in .NET 1.1, almost nobody did it - but now it's fairly common. Similarly with the use of lambda expressions - somebody was first.

evil it's most definitely evil.