Build your own CAB Part #9 – Domain Centric Validation with the Notification Pattern

Buckle up, because this is going to be a long post with more pedantry than you can shake a stick at.  As I was writing this I found some good examples of some of the design principles related to Orthogonal Code, so I made some digressions just to bring up these concepts in the context of real code.  The majority of the sample code is the very validation code we’re using on my current project for generic validation, so it better damn well work.  I’m pretty happy with this solution so far, and it’s made the validation easy to implement and test.  I promise to make up for the absurd length of this post by taking about a week off from posting starting right now.

First, here’s the preceding posts:

  1. Preamble
  2. The Humble Dialog Box
  3. Supervising Controller
  4. Passive View
  5. Presentation Model
  6. View to Presenter Communication
  7. Answering some questions
  8. What’s the Model?
  9. Assigning Responsibilities in a Model View Presenter Architecture

And for that matter, Bil Simser took a different tack on this exact subject last week.

 

 

Domain Centric Validation

As I said in the last post, it’s highly advantageous to put the validation rules into the Model classes.  Just to recap, I’ll rattle off four reasons why I want my validation rules in my Model classes:

  1. Validation is mostly a business logic function anyway, and purely for the sake of cohesion it makes sense to put business rules into business classes.  As much as possible, I want related business rules in a single place rather than scattered about my code.
  2. Since it’s fairly common to have a single Model class edited in multiple screens, I want to reuse the validation logic consistently across these different screens.  More importantly, I want to eliminate duplicated logic between these screens.  It’s going to be much easier to avoid duplication by placing this functionality in the Model than it would be to put it in each Presenter or View.  I know somebody is going to bring up the idea of drag n’drop validator’s, but even those are potentially easy to use, the potential duplication can easily become a tax — especially as your validation rules change.
  3. By decoupling the validation logic from the View and the backend, we’ve made these validation rules easy to test.  The easiest possible type of unit testing is simple state based testing.  Push a couple values into a single object and check the return value with no interaction with anything else.  Clear sailing ahead.
  4. I’m going to content that It’s easier to read the validation logic.  The downsides of Rapid Application Development (RAD) approaches are widely known, but for me the worst part is that I think RAD designers and wizards obscure the meaning of code and camouflage the functionality in design time goo.

Ok, that’s a lot of hot air about why we want to do domain centric validation, but how do I do it?  My current project is doing domain centric validation, and so far I’m thrilled with how it’s turning out.  Here’s our secret sauce (ok, it’s not that secret because it’s a documented design pattern):

 

The Notification Pattern

In doing validation on user input there are two main tasks:

  1. Perform the validation and create meaningful validation messages.
  2. Display these validation messages to the user on the screen in a meaningful way.  In WinForms development we’ve got the handy ErrorProvider class that probably meets the needs of most scenarios.

Let me emphasize this a little bit more, we have two separate concerns:  validation rules and screen presentation of validation failures.  As always, we can make our development simpler by tackling one problem at a time.  The advantage in testability, reuse, and understandability I mentioned above is largely predicated on separating the validation logic from the screen machinery. 

Assuming you’ve accepted my advice to separate the two tasks and make the validation logic completely independent of the presentation machinery, we can move onto the next question.  How can we marshal the validation messages to the View in a way to simplify the presentation of validation messages?  In other words, how does a validation message get put into the screen at the right place?  There is a ready made answer for us, just use the Notification pattern as a convenient way to package up validation messages.

From Martin Fowler, the Notification pattern is a

An object that collects together information about errors and other information in the domain layer and communicates it to the presentation.

Let’s take a look at my project’s Notification structure.  The first piece is a class called NotificationMessage (the code below is somewhat elided) that’s simply a single validation error consisting of the message itself and the name of the Property on the Model that the message applies to:

    public class NotificationMessage : IComparable

    {

        private string _fieldName;

        private string _message;

 

 

        public NotificationMessage(string fieldName, string message)

        {

            _fieldName = fieldName;

            _message = message;

        }

 

 

        public string FieldName

        {

            get { return _fieldName; }

            set { _fieldName = value; }

        }

 

        public string Message

        {

            get { return _message; }

            set { _message = value; }

        }

 

        // Override the Equals method to make declarative testing easy

        public override bool Equals(object obj)

        {

            if (this == obj) return true;

            NotificationMessage notificationMessage = obj as NotificationMessage;

            if (notificationMessage == null) return false;

            return Equals(_fieldName, notificationMessage._fieldName) && Equals(_message, notificationMessage._message);

        }

 

 

        // Override the ToString() method to create more descriptive messages within

        // xUnit testing assertions

        public override string ToString()

        {

            return string.Format(“Field {0}:  {1}”, _fieldName, _message);

        }

 

 

    }

For reasons that will be clear in the section on consuming a Notification, it’s very useful to tie the messages directly to the property names.  The second part is the Notification class itself.  It’s not much more than a collection of NotificationMessage objects:

    public class Notification

    {

        public static readonly string REQUIRED_FIELD = “Required Field”;

        public static readonly string INVALID_FORMAT = “Invalid Format”;

 

        private List<NotificationMessage> _list = new List<NotificationMessage>();

 

        public bool IsValid()

        {

            return _list.Count == 0;

        }

 

        public void RegisterMessage(string fieldName, string message)

        {

            _list.Add(new NotificationMessage(fieldName, message));

        }

 

        public string[] GetMessages(string fieldName)

        {

            List<NotificationMessage> messages = _list.FindAll(delegate(NotificationMessage m) { return m.FieldName == fieldName; });

            string[] returnValue = new string[messages.Count];

            for (int i = 0; i < messages.Count; i++)

            {

                returnValue[i] = messages[i].Message;

            }

 

            return returnValue;

        }

 

        public NotificationMessage[] AllMessages

        {

            get

            {

                _list.Sort();

                return _list.ToArray();

            }

        }

 

        public bool HasMessage(string fieldName, string messageText)

        {

            NotificationMessage message = new NotificationMessage(fieldName, messageText);

            return _list.Contains(message);

        }

    }

Easy enough right?  You’ve got everything you need to do domain centric validation — except for all the stuff around the Notification class that does all the real work.  Details.  Or as my Dad’s construction crew will say after day one on a new project, “all we lack is finishing up.”

 

Filling up the Notification

The first design goal is simply to come up with a way for a Model object to create Notification objects.  Most validation rules are very simple and take one of a handful of forms, so it’s worth our while to make the implementation of these simple rules as quick and declarative as possible.  We also need to relate any and all validation messages to the proper field.  Since this is .Net, the easiest usage scenario is simple attributes that we can use to decorate property declarations.  Using attributes comes with the great advantage of quickly tying a validation rule to a particular property.

Using attributes always requires some sort of bootstrapping code that finds and acts on the attributes decorating code, but I’m going follow my own “Test Small Before Testing Big” rule.  Let’s put off the overall validation calculation to tackle the very small goal of creating validation attributes.  Once we have the shape of the attributes and maybe the Model class down, the validation coordination code largely falls out.

Don’t use the attributes as just markers though.  The actual validation logic should reside in the attribute itself to allow for easier expansion of our validation rules.  This is a good example of the Open/Closed Principle.  We can create all new validation logic by implementing a whole new ValidationAttribute without having to modify any existing code.  That’s good stuff.  I think this is also an example of Craig Larman’s Protected Variations concept.

All of our validation attributes inherit from the ValidationAttribute shown below:

 

    [AttributeUsage(AttributeTargets.Property)]

    public abstract class ValidationAttribute : Attribute

    {

        private PropertyInfo _property;

 

        public void Validate(object target, Notification notification)

        {

            object rawValue = _property.GetValue(target, null);

            validate(target, rawValue, notification);

        }

 

        // Helper method to write validation messages to a Notification

        // object with the correct Property name

        protected void logMessage(Notification notification, string message)

        {

            notification.RegisterMessage(Property.Name, message);

        }

 

        // A Template Method for the actual validation logic

        protected abstract void validate(object target, object rawValue, Notification notification);

 

        // The Property of the targeted class

        // that’s being validated

        public PropertyInfo Property

        {

            get { return _property; }

            set { _property = value; }

        }

 

        public string PropertyName

        {

            get

            {

                return _property.Name;

            }

        }

    }

 

Attributes don’t find themselves, so we’ll need to “push” the correct actual System.Reflection.PropertyInfo object to the ValidationAttribute objects, so there’s an open getter/setter for the PropertyInfo.  The validation will work by first finding all of the special validation attributes, attaching the proper PropertyInfo’s, and looping through each ValidationAttribute and calling the Validate(target, notification) method.  All the ValidationAttribute classes do is register messages on a Notification object, so there’s absolutely no coupling to either the server or the user interface.

To actually build a specific ValidationAttribute you simply inherit from ValidationAttribute and override the validate(target, rawValue, notification) Template Method.  The simplest case for a simple required field validation is shown below:

 

    [AttributeUsage(AttributeTargets.Property)]

    public class RequiredAttribute : ValidationAttribute

    {

        protected override void validate(object target, object rawValue, Notification notification)

        {

            if (rawValue == null)

            {

                logMessage(notification, Notification.REQUIRED_FIELD);

            }

        }

    }

In real life you’d have to enhance this a bit to handle primitive types that aren’t nullable, but right now this is doing everything my project needs.  Using this little monster is as simple as marking a Property like this;

 

        [Required]

        public string Name

        {

            get { return _name; }

            set { _name = value; }

        }

or combine attributes:

        [Required, GreaterThanZero]

        public double? BaseAmount

        {

            get { return _baseAmount; }

            set { _baseAmount = value; }

        }

 

Of course, some rules are going to be too complex or simply too rare to justify building an attribute (think about rules that only apply in a certain state or involve many fields).  To allow for these more complex cases, I chose to use a simple marker interface called IValidated.

    public interface IValidated

    {

        void Validate(Notification notification);

    }

A Model class can implement this interface as a kind of hook to perform any sort of complex validation that just doesn’t fit into the attribute-based validation.  There’s a bit of a design point I’d like to make here.  This little IValidated interface is an example of the Tell, Don’t Ask principle in action.  Rather than querying the attributes and the validated object to decide what rules to enforce, we can create far more variations and allow for far more extension by just telling the object being validated and each attribute class to add it’s messages to the Notification object. 

A quick side note.  If you’re going to build something like this for yourself, I’d recommend building the first couple specific cases, then doing an Extract Superclass refactoring to “lift” the common template into a superclass.  Starting by designing the abstract class can sometimes lead into a black hole.  When I built this code I created the RequiredFieldAttribute first then used ReSharper to create the Supertype.

And yes, I do know about the Validation Application Block, but it’s kind of fun and fairly easy to write our own to do exactly what we want.  Besides, I’m not sure how well the Validation Block plays in the Notification scenario.  My real inspiration here is the Notification-style validation baked into ActiveRecord in Ruby on Rails.  The same kind of thing that we did with attributes in C# is potentially more declarative in a Rails model.  Just coincidentally, Steve Eichert has a cool writeup on this subject at Create DDD style specifications in Ruby with ActiveSpec.

 

Putting the Notification Together

We’ve got the Notification class, some working ValidationAttribute classes, and the IValidated hook interface.  Now we need a Controller class of some kind to glue all of these pieces together.  With my nearly infinite creativity, I’ve named this class in our system “Validator.”  The next task is simply to scan a Type and create a list of ValidationAttribute objects for each declared attribute.  That’s done with this static method:

 

        // Find all the ValidationAttribute’s for a given Type, and connect

        // each ValidationAttribute to the correct Property

        public static List<ValidationAttribute> FindAttributes(Type type)

        {

            List<ValidationAttribute> atts = new List<ValidationAttribute>();

 

            foreach (PropertyInfo property in type.GetProperties())

            {

                Attribute[] attributes = Attribute.GetCustomAttributes(property, typeof (ValidationAttribute));

                foreach (ValidationAttribute attribute in attributes)

                {

                    attribute.Property = property;

                    atts.Add(attribute);

                }

            }

 

            return atts;

        }

Once that method is unit tested, we can move onto the core task of validating an object.  That’s accomplished with the method below.

 

        public static Notification ValidateObject(object target)

        {

            // Find all the ValidationAttribute’s attached to the properties

            // of the target Type

            List<ValidationAttribute> atts = scanType(target.GetType());

            Notification notification = new Notification();

 

            // Iterate through each ValidationAttribute and give each

            // a chance to add validation messages

            foreach (ValidationAttribute att in atts)

            {

                att.Validate(target, notification);

            }

 

            // And if the target implements IValidated, call the

            // Validate(Notification) method to do the special cases

            if (target is IValidated)

            {

                ((IValidated)target).Validate(notification);

            }

 

            return notification;

        }

I’ve elided the code here for brevity, but the first thing ValidateObject(object) does is to call its scanType(Type) method to find the list of ValidationAttribute’s declared for target.GetType().  Since Reflection isn’t the fastest operation in the world, I do cache the list of ValidationAttribute objects for each Type on the first access for that Type. 

Once we have the ValidationAttribute list everything else just falls out.

Testing Validation Logic

One of the best things about this approach is how easy automated testing of the validation logic becomes.  Just create the class under test, pump in some property values, create a Notification from its current state, and finally compare the Notification object to the expected results.  One of Jeremy’s Laws of TDD is to “go declarative whenever possible” in testing.  We’re using Fit tests[LINK] to perform declarative testing of our validation rules, and this is exactly the kind of scenario where Fit shines.  I will often embed bits of Fit tests directly into NUnit tests for developer tests, especially for set based functionality.  This might not be very interesting to you unless you already use the FitnesseDotNet engine, but we create and define the state of one of our Model objects inside a Fit table, then turn around and check the validation messages produced for the input.  The Fit test itself looks something like this:

 

	!|UserFixture|
|Create New|
|Name |Jeremy|
|Birthday |BLANK |
|PhoneNumber|BLANK |
|The Validation Messages Are|
|FieldName|Message |
|Name |Field Required|
|Birthday |Field Required|

The actual UserFixture class would inherit from DoFixture and provide methods to set each public property (we codegen these Fixture classes from reflecting over the targeted classes, i.e. the code generator creates a UserFixture class for User).  Once the desired state of the object is configured, the validation logic is tested by comparing the actual validation messages against the expected messages.  At the bottom of the Fit test above we simply make a declaration that the expected validation messages are the values in the nested table (the bolded, red text).  The Fit engine has a facility called the RowFixture that makes this type of set comparison very easy.  The RowFixture to check the validation messages is triggered by this method on the UserFixture class:

 

        public Fixture TheValidationMessagesForFieldAre(string fieldName)

        {

            Notification notification = Validator.ValidateObject(CurrentTrade);

            string[] messages = notification.GetMessages(fieldName);

 

            return new StringArrayFixture(messages);

        }

This section might not be all that useful to you if you’re not familiar with the mechanics of Fit testing, but then again, you might want to go give Fit another try.  It’s goofy alright, but it’s very useful in the right spot.

Consuming Notifications

Alrighty then!  We’ve got ourselves a Notification object that relates all the user input failure messages to the relevant properties of the Model.  Now we’ve just got to get these messages to the right place on the screen. In your best Church Lady voice — who knows about both the field names and the controls that edit those fields?  Could it be….   …Satan!  The data binding!  I’m not going to show it here because I suspect the code would be nasty, but you could do a recursive search through all the child Control’s and check the DataBindings collection of each child control to see if it’s bound to any property of the object being validated. 

Alternatively, you ditch the designer for data binding and put just a small Facade over the BindingDataSource class.  If you build just a tiny class that wraps BindingDataSource with something like “BindControlToProperty(control, propertyName)” you could capture a Dictionary of the controls by field name along that way that could make attaching the errors much simpler.  One of the themes I was trying to get across with my WinForms patterns talk at DevTeach was that sometimes a codecentric solution can be much more efficient than the equivalent work with designers.

Or, if that sounds as nasty to you as it does to me, you could just write your own synchronization mechanism that bakes in the functionality to attach validation messages to controls.  If you thought I was nuts to suggest that mere mortals could write their own CAB analogue, you’ll really flip out once I admit that I’ve written a replacement for WinForms data binding to do screen synchronization (so far the Crackpot idea is working out fairly well).  I’ll give it a much better treatment in the post on MicroController, but for now, here’s a sneak peek at the code we use to attach validation messages to the proper screen element with an ErrorProvider.

 

        public void ShowErrorMessages(Notification notification)

        {

            foreach (IScreenElement element in _elements)

            {

                string[] messages = notification.GetMessages(element.FieldName);

                element.SetErrors(messages);

            }

        }

Each IScreenElement is what I call a “MicroController” that governs the behavior and binding of a single control element.  Each IScreenElement already ”knows” the ErrorProvider for the form or control by this point, so it just needs to turn around and use the ErrorProvider to attach messages to its internal control.

About Jeremy Miller

Jeremy is the Chief Software Architect at Dovetail Software, the coolest ISV in Austin. Jeremy began his IT career writing "Shadow IT" applications to automate his engineering documentation, then wandered into software development because it looked like more fun. Jeremy is the author of the open source StructureMap tool for Dependency Injection with .Net, StoryTeller for supercharged acceptance testing in .Net, and one of the principal developers behind FubuMVC. Jeremy's thoughts on all things software can be found at The Shade Tree Developer at http://codebetter.com/jeremymiller.
This entry was posted in Build your own CAB, Design Patterns, Featured. Bookmark the permalink. Follow any comments here with the RSS feed for this post.