Jeremy D. Miller -- The Shade Tree Developer

Sponsors

The Lounge

News

Advertisement

Images in this post missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at imagehelp@codebetter.com
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++)

            {

                returnValueIdea = messagesIdea.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.


Posted 06-13-2007 8:28 AM by Jeremy D. Miller

[Advertisement]

Comments

Bill Pierce wrote re: Build your own CAB Part #9 - Domain Centric Validation with the Notification Pattern
on 06-13-2007 9:59 AM

Lovin' it, as usual.  Use what works until it doesn't.  I think this works most of the time but I'll put a plug in here for putting your validation logic in a separate class.  

Our app is purchased by several organizations that use it internally.  Using your example fields... some of them want PhoneNumber to be required, some of them don't, some of them want PhoneNumber validated against a national phone number database, a custom regex string, an XML file with valid company extensions, ... you get the point.  By having the validation logic in a separate class we can easily code a custom validator on a case by case basis (and extrapolate common customizations into configuration in v.Next) and have it injected through DI.  

D Rapp wrote re: Build your own CAB Part #9 - Domain Centric Validation with the Notification Pattern
on 06-13-2007 10:02 AM

All looks vaguely familiar...  Though I'm not a fan of the IValidated interface.  Then validation logic exists in two locations and moreover you need to manually input the corresponding property names into the Notification object in your validate() method.  Thinking out loud, for complex validations, is there a way to integrate generics throughout the notification and validator code to inject strongly typed objects into the custom validation attributes?  Then you can compare multiple properties together with ease...

Jeremy D. Miller wrote re: Build your own CAB Part #9 - Domain Centric Validation with the Notification Pattern
on 06-13-2007 10:08 AM

@Derrick,

It should look familiar since you wrote it big guy.  The logic is declared all in one place though.   The only time the manual property declaration comes into play is for the special IValidated method.  We're codegen'ing off constants for the field names to eliminate the soft strings.  If the property names change, the [Class]Fields class constants change and the new code would break at compile time.  

Rubyesque symbols would be very nice here too.

For multi-field validations, we are doing it by pushing in a property name.  Your suggestion about generics is worth looking into.

Dave Donaldson wrote re: Build your own CAB Part #9 - Domain Centric Validation with the Notification Pattern
on 06-13-2007 10:40 AM

Don't know if you know about it, but EViL is out there as well for validation attributes (http://www.codeplex.com/evil).

John Papa wrote re: Build your own CAB Part #9 - Domain Centric Validation with the Notification Pattern
on 06-17-2007 1:11 PM

Dave ... I have used EViL a bit and found it very useful. Nice to reuse those basic validation rules.

Greg wrote re: Build your own CAB Part #9 - Domain Centric Validation with the Notification Pattern
on 06-19-2007 2:53 AM

Jeremy I like the work but one thing in it throws a big red flag for me, the attributes and the objects themselves controlling their validation. I like the attributes in that they are simple and easily readable through metadata which also allows for a richer domain language.

Often times however a single domain is reused in many contexts (especially shared areas of a domain) and if this were to happen to a domain with its logic implemented as above it would be doomed because there is no good way to say this rule only applies in situation X.

What I see happenning if this occurred (providing someone tried to stay within the model for cost or intelligence reasons) would be two-fold, first the attributes would slowly disappear on all rules that were variant; my guess is that they would be moved into the objects Validate method as hard coded code or there would be some kind ofhokey new attribute RequiredWhen(SomeGlobalCondition) would appear. Either way this type of branching is generally frowned upon in comparison with the alternative of injecting IRule objects and having them actually generate the notifications.

The next issue obviously applies within the validate method itself and is similar things like if(IShouldDoThisValidation) { }.

Perhaps some of what you are presenting here could be built on top of a architecture more like that where for common cases this is used but it is used only as metadata to populate an IRule type architecture (i.e. in generating the rules to be run for an object and caching them you also allow attributes where the attributes meet the IRule interface)

Also in my experience the ability to create composite rules is quite useful and allows for a much more dynamic system to be created.

Jeremy D. Miller wrote re: Build your own CAB Part #9 - Domain Centric Validation with the Notification Pattern
on 06-19-2007 5:06 AM

Greg,

There's no doubt that this little solution is really limited to simpler systems with invariant rules, but it's working great for my current project that meets that criteria.

I would certainly agree with injecting IRule strategy classes of some kind for branching or conditional logic, especially if you need extensibility or client specific rules.

Wire it together with StructureMap and that sounds like an awesome approach to me.

Kevin Dente wrote re: Build your own CAB Part #9 - Domain Centric Validation with the Notification Pattern
on 06-19-2007 8:48 PM

Nice. But how would you handle the case, like with ASP.NET form validation, where (some of) the validation logic lives on a separate tier than the domain objects (in client-side Javascript, specifically)?

Jeremy D. Miller wrote re: Build your own CAB Part #9 - Domain Centric Validation with the Notification Pattern
on 06-19-2007 10:30 PM

Kevin,

Don't know.  For server side validation the response message could contain a Notification or something easily transmittable to the very same Notification that we use to attach the messages to the UI.

I don't know offhand what I'd do in a web development environment.  You've got a different set of tricks to play with Javascript and DHTML as well.

the ‘bee log / The Smart DTO wrote the &#8216;bee log / The Smart DTO
on 06-21-2007 12:54 AM

Pingback from  the &#8216;bee log  / The Smart DTO

Jeremy D. Miller -- The Shade Tree Developer wrote Build your own CAB Part #10 - Unit Testing the UI with NUnitForms
on 06-26-2007 9:58 PM

I&#39;ve long, long since left the rails of &quot;Build your own CAB&quot; topics and wandered off into

Jeremy D. Miller -- The Shade Tree Developer wrote Build your own CAB #11 - Event Aggregator
on 06-29-2007 11:12 AM

I will finish &quot;Build your own CAB&quot; at least before Acropolis hits and makes it all obsolete

Jeremy D. Miller -- The Shade Tree Developer wrote Build your own CAB #13 - Embedded Controllers with a Dash of DSL
on 07-06-2007 12:40 PM

Just to continue the world&#39;s longest run on sentence. Before I start, here&#39;s the table of contents

HMK's Spurious Thoughts wrote The Humble Dialog Box & more...
on 07-13-2007 1:06 PM

Even if you are not into .NET, WinForms etc. this series by Jeremy D. Miller is a great one to follow. Posts so far: Preamble The Humble Dialog Box Supervising Controller Passive View Presentation Model View to Presenter Communication Answering...

Jeremy D. Miller -- The Shade Tree Developer wrote Build your own CAB #14: Managing Menu State with MicroController's, Command's, a Layer SuperType, some StructureMap Pixie Dust, and a Dollop of Fluent Interface
on 07-24-2007 5:18 AM

The title is a mouthful and accurately implies an alarmingly high jargon to code ration, but I just didn&#39;t

Jeremy D. Miller -- The Shade Tree Developer wrote The Build Your Own CAB Series Table of Contents
on 07-25-2007 9:21 PM

Yes, this is overdue. Here is an introduction and table of contents to my &quot;Build Your Own CAB&quot;

Jeremy D. Miller -- The Shade Tree Developer wrote Build your own CAB #14: Managing Menu State with MicroController's, Command's, a Layer SuperType, some StructureMap Pixie Dust, and a Dollop of Fluent Interface
on 07-26-2007 10:57 AM

The title is a mouthful and accurately implies an alarmingly high jargon to code ration, but I just didn&#39;t

Blake wrote re: Build your own CAB Part #9 - Domain Centric Validation with the Notification Pattern
on 08-24-2007 3:36 PM

I'm stuck on displaying lists in grid controls (i.e. WinForms's DataGridView).  How can you resolve a field name to a specific item in the list?  For example, if you have a list named 'Names' that exposes 'Name' objects that have 'FirstName' and 'LastName' properties, an error might reference the 'Names.FirstName' field, but how would you know which item in the 'Names' list the error actually refers to?

All Night Coder - Today’s Top Blog Posts on Programming - Powered by SocialRank wrote All Night Coder - Today&#8217;s Top Blog Posts on Programming - Powered by SocialRank
on 10-01-2007 5:08 AM

Pingback from  All Night Coder - Today&#8217;s Top Blog Posts on Programming - Powered by SocialRank

All Night Coder - Today’s Top Blog Posts on Programming - Powered by SocialRank wrote All Night Coder - Today&#8217;s Top Blog Posts on Programming - Powered by SocialRank
on 10-01-2007 5:13 AM

Pingback from  All Night Coder - Today&#8217;s Top Blog Posts on Programming - Powered by SocialRank

All Night Coder - Today’s Top Blog Posts on Programming - Powered by SocialRank wrote All Night Coder - Today&#8217;s Top Blog Posts on Programming - Powered by SocialRank
on 10-01-2007 5:14 AM

Pingback from  All Night Coder - Today&#8217;s Top Blog Posts on Programming - Powered by SocialRank

All Night Coder - Today’s Top Blog Posts on Programming - Powered by SocialRank wrote All Night Coder - Today&#8217;s Top Blog Posts on Programming - Powered by SocialRank
on 10-01-2007 8:07 AM

Pingback from  All Night Coder - Today&#8217;s Top Blog Posts on Programming - Powered by SocialRank

All Night Coder - Today’s Top Blog Posts on Programming - Powered by SocialRank wrote All Night Coder - Today&#8217;s Top Blog Posts on Programming - Powered by SocialRank
on 10-01-2007 8:10 AM

Pingback from  All Night Coder - Today&#8217;s Top Blog Posts on Programming - Powered by SocialRank

All Night Coder - Today’s Top Blog Posts on Programming - Powered by SocialRank wrote All Night Coder - Today&#8217;s Top Blog Posts on Programming - Powered by SocialRank
on 10-01-2007 8:10 AM

Pingback from  All Night Coder - Today&#8217;s Top Blog Posts on Programming - Powered by SocialRank

All Night Coder - Today’s Top Blog Posts on Programming - Powered by SocialRank wrote All Night Coder - Today&#8217;s Top Blog Posts on Programming - Powered by SocialRank
on 10-01-2007 8:10 AM

Pingback from  All Night Coder - Today&#8217;s Top Blog Posts on Programming - Powered by SocialRank

All Night Coder - Today’s Top Blog Posts on Programming - Powered by SocialRank wrote All Night Coder - Today&#8217;s Top Blog Posts on Programming - Powered by SocialRank
on 10-01-2007 8:11 AM

Pingback from  All Night Coder - Today&#8217;s Top Blog Posts on Programming - Powered by SocialRank

All Night Coder - Today’s Top Blog Posts on Programming - Powered by SocialRank wrote All Night Coder - Today&#8217;s Top Blog Posts on Programming - Powered by SocialRank
on 10-01-2007 8:11 AM

Pingback from  All Night Coder - Today&#8217;s Top Blog Posts on Programming - Powered by SocialRank

All Night Coder - Today’s Top Blog Posts on Programming - Powered by SocialRank wrote All Night Coder - Today&#8217;s Top Blog Posts on Programming - Powered by SocialRank
on 10-01-2007 8:12 AM

Pingback from  All Night Coder - Today&#8217;s Top Blog Posts on Programming - Powered by SocialRank

All Night Coder - Today’s Top Blog Posts on Programming - Powered by SocialRank wrote All Night Coder - Today&#8217;s Top Blog Posts on Programming - Powered by SocialRank
on 10-01-2007 8:12 AM

Pingback from  All Night Coder - Today&#8217;s Top Blog Posts on Programming - Powered by SocialRank

All Night Coder - Today’s Top Blog Posts on Programming - Powered by SocialRank wrote All Night Coder - Today&#8217;s Top Blog Posts on Programming - Powered by SocialRank
on 10-01-2007 8:13 AM

Pingback from  All Night Coder - Today&#8217;s Top Blog Posts on Programming - Powered by SocialRank

All Night Coder - Today’s Top Blog Posts on Programming - Powered by SocialRank wrote All Night Coder - Today&#8217;s Top Blog Posts on Programming - Powered by SocialRank
on 10-01-2007 8:13 AM

Pingback from  All Night Coder - Today&#8217;s Top Blog Posts on Programming - Powered by SocialRank

All Night Coder - Today’s Top Blog Posts on Programming - Powered by SocialRank wrote All Night Coder - Today&#8217;s Top Blog Posts on Programming - Powered by SocialRank
on 10-01-2007 8:13 AM

Pingback from  All Night Coder - Today&#8217;s Top Blog Posts on Programming - Powered by SocialRank

All Night Coder - Today’s Top Blog Posts on Programming - Powered by SocialRank wrote All Night Coder - Today&#8217;s Top Blog Posts on Programming - Powered by SocialRank
on 10-01-2007 8:15 AM

Pingback from  All Night Coder - Today&#8217;s Top Blog Posts on Programming - Powered by SocialRank

All Night Coder - Today’s Top Blog Posts on Programming - Powered by SocialRank wrote All Night Coder - Today&#8217;s Top Blog Posts on Programming - Powered by SocialRank
on 10-01-2007 4:44 PM

Pingback from  All Night Coder - Today&#8217;s Top Blog Posts on Programming - Powered by SocialRank

All Night Coder - Today’s Top Blog Posts on Programming - Powered by SocialRank wrote All Night Coder - Today&#8217;s Top Blog Posts on Programming - Powered by SocialRank
on 10-02-2007 1:53 PM

Pingback from  All Night Coder - Today&#8217;s Top Blog Posts on Programming - Powered by SocialRank

All Night Coder - Today’s Top Blog Posts on Programming - Powered by SocialRank wrote All Night Coder - Today&#8217;s Top Blog Posts on Programming - Powered by SocialRank
on 10-02-2007 1:53 PM

Pingback from  All Night Coder - Today&#8217;s Top Blog Posts on Programming - Powered by SocialRank

All Night Coder - Today’s Top Blog Posts on Programming - Powered by SocialRank wrote All Night Coder - Today&#8217;s Top Blog Posts on Programming - Powered by SocialRank
on 10-02-2007 1:53 PM

Pingback from  All Night Coder - Today&#8217;s Top Blog Posts on Programming - Powered by SocialRank

Jeremy D. Miller -- The Shade Tree Developer wrote Build your own CAB #15 - MicroControllers
on 10-21-2007 9:13 PM

After a bit of a hiatus and a fair amount of pestering, I&#39;m back and ready to continue the &quot;Build

Jeremy D. Miller -- The Shade Tree Developer wrote Resources from my DevTeach talks
on 11-29-2007 12:03 PM

To everybody that attended one of my talks at DevTeach this week. All of the materials are now online

FZelle wrote re: Build your own CAB Part #9 - Domain Centric Validation with the Notification Pattern
on 01-19-2008 11:57 AM

I Know it is late, but why don't you use the IDataErrorInfo that is used in the FW?

Jeremy D. Miller wrote re: Build your own CAB Part #9 - Domain Centric Validation with the Notification Pattern
on 01-20-2008 9:40 AM

@FZelle,

Well, the main reason is that I had to go look up "IDataErrorInfo" after your comment.  I think I did research that  last spring, but passed on it for some reason.  Even so, in the system that I stole this sample from, the Model classes in the UI were the actual Domain Model classes.  I didn't want to have to put any kind of IPropertyNotifyChanged/IBindingList/IDataErrorInfo classes on these classes.

So yes, you could use IDataErrorInfo for getting the error messages to the screen elements, but this post was really about a way to put the validation messages onto the Model classes in the first place.  You could do both the validation scheme I showed up above (which is basically what EntLib and a couple others do to) and expose the IDataErrorInfo interface for data binding support.

dave^2=-1 wrote Domain Centric Validation with the Notification Pattern
on 02-01-2008 5:53 AM

Jeremy D. Miller as churned out another fantastic post on Domain Centric Validation with the Notification

http://129568.nant.codebetter.com/blogs/jeremy.miller/archive/2007/06/13/build-your-own-cab-part-9-domain-centric-validation-with-the-notification-pattern.aspx wrote http://129568.nant.codebetter.com/blogs/jeremy.miller/archive/2007/06/13/build-your-own-cab-part-9-domain-centric-validation-with-the-notification-pattern.aspx
on 03-24-2008 3:56 AM
http://139641.subversion.codebetter.com/blogs/jeremy.miller/archive/2007/06/13/build-your-own-cab-part-9-domain-centric-validation-with-the-notification-pattern.aspx wrote http://139641.subversion.codebetter.com/blogs/jeremy.miller/archive/2007/06/13/build-your-own-cab-part-9-domain-centric-validation-with-the-notification-pattern.aspx
on 03-28-2008 5:53 AM
http://sgentile.codebetter.com/blogs/jeremy.miller/archive/2007/06/13/build-your-own-cab-part-9-domain-centric-validation-with-the-notification-pattern.aspx wrote http://sgentile.codebetter.com/blogs/jeremy.miller/archive/2007/06/13/build-your-own-cab-part-9-domain-centric-validation-with-the-notification-pattern.aspx
on 03-28-2008 5:54 AM
http://www2.codebetter.com/blogs/jeremy.miller/archive/2007/06/13/build-your-own-cab-part-9-domain-centric-validation-with-the-notification-pattern.aspx wrote http://www2.codebetter.com/blogs/jeremy.miller/archive/2007/06/13/build-your-own-cab-part-9-domain-centric-validation-with-the-notification-pattern.aspx
on 03-28-2008 5:55 AM
Oswaldo wrote re: Build your own CAB Part #9 - Domain Centric Validation with the Notification Pattern
on 04-04-2008 3:14 AM

Hey, Jeremy I believe that you should check out the early draft of Java's Bean Validation Framework as I believe that it adresses some of the concerns expressed by FZelle

Links:

in.relation.to/.../BeanValidationSneakPeekPartI

jcp.org/.../detail

Oswaldo wrote re: Build your own CAB Part #9 - Domain Centric Validation with the Notification Pattern
on 04-04-2008 3:16 AM

Sorry I meant Greg instead of FZelle

江南白衣 wrote Unsaved Changes When CAB Application Closes: The Notification Pattern(转)
on 08-01-2008 2:34 PM

Occasionally this question pops up on the CAB message boards: How do I prevent my application from closing if the user has unsaved changes? Turns out that there’s a very simple pattern you can utilize to handle this situation. It’s called the Notification

Jeremy D. Miller -- The Shade Tree Developer wrote A Gentle Quickstart for StructureMap 2.5
on 11-30-2008 10:56 PM

The most general question I get with StructureMap is “how do I get started?” Personally, I’d recommend

Community Blogs wrote A Gentle Quickstart for StructureMap 2.5
on 11-30-2008 11:48 PM

The most general question I get with StructureMap is “how do I get started?” Personally, I’d recommend

A Gentle Quickstart for StructureMap 2.5 - taccato! trend tracker, cool hunting, new business ideas wrote A Gentle Quickstart for StructureMap 2.5 - taccato! trend tracker, cool hunting, new business ideas
on 12-02-2008 10:15 AM

Pingback from  A Gentle Quickstart for StructureMap 2.5 - taccato! trend tracker, cool hunting, new business ideas

Sam Gentile's Blog wrote New and Notable 170
on 12-02-2008 9:35 PM

Design Patterns/Software Design/Agile The Presenter First Pattern End to End, or, Another Run on the Hamster Wheel of Life Build your own CAB Part #8 - Assigning Responsibilities in a Model View Presenter Architecture Build your own CAB Part #9 - Domain

A Gentle Quickstart for StructureMap 2.5 - taccato! trend tracker, cool hunting, new business ideas wrote A Gentle Quickstart for StructureMap 2.5 - taccato! trend tracker, cool hunting, new business ideas
on 12-03-2008 11:04 AM

Pingback from  A Gentle Quickstart for StructureMap 2.5 - taccato! trend tracker, cool hunting, new business ideas

A Gentle Quickstart for StructureMap 2.5 - taccato! trend tracker, cool hunting, new business ideas wrote A Gentle Quickstart for StructureMap 2.5 - taccato! trend tracker, cool hunting, new business ideas
on 12-04-2008 11:09 AM

Pingback from  A Gentle Quickstart for StructureMap 2.5 - taccato! trend tracker, cool hunting, new business ideas

Chris Holmes Online » Blog Archive » Unsaved Changes When CAB Application Closes: The Notification Pattern wrote Chris Holmes Online &raquo; Blog Archive &raquo; Unsaved Changes When CAB Application Closes: The Notification Pattern
on 03-05-2009 11:01 PM

Pingback from  Chris Holmes Online  &raquo; Blog Archive   &raquo; Unsaved Changes When CAB Application Closes: The Notification Pattern

Add a Comment

(required)  
(optional)
(required)  
Remember Me?