.NET Domain Object validation through delegation

Over the years I’ve seen a dozen different ways to validate domain objects in any MVC framework. Everyone has got their own favorite method. I’ve recently been presented with the same problem again and recalled a particularly elegant solution I implemented once in C# that I figured I would share.

The delegate accepts a business object Interface and an error collection. The Interface defines one method called Validate. The error collection must be passed by reference due to how delegates are stacked. You’ll see more on this later.

public delegate void ValidationDelegate(IBusinessObject entity, ref ErrorCollection errors);

Next on my base domain class I defined the delegate property and a validation method.

public abstract class BaseDomainObject
{
  public virtual event ValidationDelegate Validators;

  public virtual bool Validate(ref ErrorCollection errors)
  {
    if (Validators != null)
    {
      Validators(this, ref errors);
    }
    return (errors.Count == 0);
  }
}

The ErrorCollection class can be a collection of your choice. But what is important is that it is passed by reference. For each of my domain objects I create at least one validator. The benefit to this is you can programmatically determine what validators you want to run and when.

public class ConsumerValidators
{
  public static void ValidateConsumerName(object obj, ref ErrorCollection errors)
  {
    if (!(obj is Consumer))
    {
       throw new Exception(“ValidateConsumerName passed invalid object of type: ” + obj.GetType().Name);
    }

    Consumer c = (Consumer)obj;

     if (c.Firstname == null || c.Firstname.Length == 0)
    {
       errors.Add(“First name is a required field.”);
    }

    if (c.Lastname == null || c.Lastname.Length == 0)
     {
         errors.Add(“Last name is a required field.”);
    }
    }
}

Now in your control class. You tell the domain object what validators to execute then execute them. For instance:

public class ConsumerController
{
  public bool SaveConsumer(Consumer c, ref ErrorCollection errorCollection)
  {
    c.Validators += ConsumerValidators.ValidateConsumerName;
    c.Validators += ConsumerValidators.ValidateConsumerEmail;

    if(cc.Validate(ref errorCollection))
    {
      return cc.Save();
    } else {
      return false;
    }
    }
}

Simple and elegant right? Any comments much appreciated

This entry was posted in C#, programming, tech and tagged , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s