Sponsored By Aspose - File Format APIs for .NET

Aspose are the market leader of .NET APIs for file business formats – natively work with DOCX, XLSX, PPT, PDF, MSG, MPP, images formats and many more!

Validation Application Block – Integrating It Into Your Business Layer

Validation Application Block – Integrating It Into Your Business Layer

by David Hayden, Filed: Enterprise Library 3.0 Tutorials

 

As mentioned earlier, the December 2006 CTP of Enterprise Library 3.0 was released last Friday. One of the new application blocks it contains is a Validation Application Block for validating classes in your applications. I recently wrote 4 tutorials on how to use it for those who are interested and haven't played with it already:

Of course there is always a giant step from playing with tutorials and quickstarts to getting the Enterprise Library Application Blocks integrated into your application.

Layer SuperType

Now that we have this cool Validation Application Block we want to use it with all our business objects. This should immediately send up a red flag that there will probably be some common functionality among all these business objects in how they use the Validation Application Block. Hence some type of layer supertype ( business base class ) will probably be necessary to contain common functionality to remove code redundancy.

In this case I can think of at least a couple methods common to these classes for validating them:

  •  IsValid() – Are you valid – True or False?
  • Validate() – Are you valid, and if not, tell me why?

I am also going to toss in another one for kicks:

  • IsSavable() – Are you dirty and valid – True or False?

I will treat validation as a service and hence allow it to be injected into the business object via its constructor. If not provided, I will just grab the default validator for the class using the ValidationFactory Class. Here is a pretty good start to the base class, but this is one of several possible answers and provided as food for thought:

 

public abstract class DomainObject<T> where T : class
{
    protected IValidator<T> _validationService;        
    
    private bool _isDirty = true;
    public virtual bool IsDirty
    {
        get { return _isDirty; }
    }

    #region Constructors

    public DomainObject()
    {
        _validationService = ValidationFactory.CreateValidator<T>();
    }

    public DomainObject(IValidator<T> validationService)
    {
        if (validationService == null)
            throw new ArgumentNullException("validationService", "Validation Service cannot be null");

        _validationService = validationService;
    }

    #endregion

    public virtual ValidationResults Validate()
    {
        return _validationService.Validate(this);
    }

    public bool IsValid()
    {
        return Validate().IsValid;
    }

    public bool IsSavable()
    {
        return IsDirty && IsValid();
    }
}

 

The above assumes you plan on having one set of validation rules per class. The Validation Application Block supports multiple. If you plan to use more than one set of rules, you need to allow for ruleset names to be passed by the client or within the class. 

 

Business Class

Now that we have moved most of the plumbing down to the base class, we can just decorate our class with ValidatorAttributes ( as done here ) or use a separate config file to specify the validation rules. The EmailAddressValidator below is a custom one I created, but you can use the RegEx one that comes with the block.

 

public class Subscriber : DomainObject<Subscriber>
{
    private string _name;

    [NotNullValidator]
    [StringLengthValidator(1, 200)]
    public string Name
    {
        get
        {
            return _name;
        }
        set
        {
            _name = value;
        }
    }

    private string _emailAddress;

    [NotNullValidator]
    [EmailAddressValidator]
    public string EmailAddress
    {
        get
        {
            return _emailAddress;
        }
        set
        {
            _emailAddress = value;
        }
    }

    public Subscriber() : base() { }

    public Subscriber(IValidator<Subscriber> validationService) : base(validationService) { }
}

 

Validating The Classes

As you would expect, all of the hard work of validating the classes is done by the Validation Application Block. We just need to call IsValid() or Validate() to check if a class is valid:

 

Subscriber subscriber = new Subscriber();
subscriber.Name = "David Hayden";
subscriber.EmailAddress = "test@test.com";

// Are you valid - True or False?
bool isValid = subscriber.IsValid();

// Are you valid, and if not, tell me why?
ValidationResults results = subscriber.Validate();

 

Perhaps in your Data Access Object you call IsSavable() to see if the object can be saved ( dirty and valid ). Here is a brief idea of how it could work. Most of the DAAB code is sitting behind in the DAO<T> class.

 

public class SubscriberDAO : DAO<Subscriber>, IDAO<Subscriber>
{
    #region IDAO<Subscriber> Members

    public void Insert(Subscriber subscriber)
    {
        // Can I save this?
        if (subscriber.IsSavable())
        {
            SubscriberInsertFactory insertFactory = new SubscriberInsertFactory();
            Add(subscriber, insertFactory);
        }
    }

    #endregion
}

 

If you want more thoughts on this DAO type code, look at a couple of my previous posts:

 

Conclusion

This is a brief look at how you might add the Validation Application Block to your business layer. This is just one example of many. As mentioned before, I keep a bunch of Enterprise Library 2.0 Tutorials and Enterprise Library 3.0 Tutorials on my website. Btw, this is December CTP 2006 CTP Code, so things can change before the block goes into production :)

by David Hayden

This entry was posted in Uncategorized. Bookmark the permalink. Follow any comments here with the RSS feed for this post.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>