views:

541

answers:

2

Let's say I have a POCO like so:

public class Name
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

FirstName and LastName cannot be null. Should I add in a method like this:

public List<Error> Validate()
{
    var errors = new List<Error>();

    if (String.IsNullOrEmpty(FirstName))
        errors.Add(new Error("FirstName", "You must fill out first name."));
    if (String.IsNullOrEmpty(LastName))
        errors.Add(new Error("LastName", "You must fill out last name."));
}

where Error is a struct that contains a NameValueDictionary. Is this a good way of doing things? I can potentially see a problem with the repository where someone attempts to save this POCO without running it through Validate() first.

+1  A: 

Consider using an aspect-oriented validation framework like xVal.

Instead of having to incorporate your validation rules directly into the code, you can add them as attributes of your properties, and offload the dependency. Your class would look like this:

public class Name
{
    [Required]
    public string FirstName { get; set; }
    [Required]
    public string LastName { get; set; }
}

To more directly answer your question, adding validation rules to your POCO is a simple way of doing things that will work, but it can get ponderous to maintain, and you'll need to enforce the Validate interface across all your objects, which is it's own headache. The aspect-oriented solution is a pretty elegant one that addresses these problems and many others.

womp
I've looked into xVal before but I found a distinct lack of documentation and examples. Perhaps I'll look into it again now that I'm using POCO's.
Daniel T.
Now that I think about it, how would you handle cases where you need more advanced validation, for example validate that a file path string points to a physical file on the hard drive?
Daniel T.
xVal lets you create custom validation attributes. Here's an example page: http://blog.codeville.net/2009/02/27/xval-08-beta-now-released/
womp
Thanks, that helps me out quite a lot!
Daniel T.
@Daniel T. - Check out the Validation Application Block (VAB) - you can write custom validators and control what gets applied when through declarative XML.
Travis Heseman
+3  A: 

I wouldn't. My POCO's tend to have different validation based on their context. "My Person objects have to have an address in this application, but they only have to have a phone number in this other application"... is the sort of thing you want to keep an eye on and be flexible for.

I'm an advocate of the anemic domain model as I typically reuse the same domain, but assign different behavior and validation based on the context (which could even be different areas of the same application).

When implementing new functionality, I typically look at my class and ask myself this question: does this seem like the responsibility of this class, or would it be more suitable for a class with a different set of responsibilities? We call this checking for "Feature Envy" and it effectively helps to separate out what the class is and is not concerned about.

Travis Heseman
Agree with your second paragraph very much. This is the exact reasons that rule engines became popular.
womp