LINQ to SQL: OnValidate () and Custom Domain Model Classes

Working through the NerdDinner Tutorial , I'm trying to find a good way to do property validation that doesn't depend on the LINQ-to-SQL spawned partial class. Here's some sample code I've done so far:

public abstract class DomainEntity
{
    public IEnumerable<ValidationError> ValidationErrors { get; private set; }

    public bool Validate()
    {
        bool isValid = false;

        if (this.ValidationErrors != null)
            this.ValidationErrors = null;

        this.ValidationErrors = this.GetValidationErrors();

        if (this.ValidationErrors.Count() == 0)
            isValid = true;

        return isValid;
    }

    protected abstract IEnumerable<ValidationError> GetValidationErrors();
}

public partial class Email : DomainEntity
{
    protected override IEnumerable<ValidationError> GetValidationErrors()
    {
        if (!this.ValidateAddress())
            yield return new ValidationError("Address", DomainResources.EmailAddressValidationErrorMessage);

        yield break;
    }

    partial void OnValidate(ChangeAction action)
    {
        bool isValid = this.Validate();

        if (!isValid)
            throw new InvalidEmailException(this);
    }

    private bool ValidateAddress()
    {
        // TODO: Use a regex to validate the email address.

        return !string.IsNullOrEmpty(this.Address);
    }
}

      

Where email is a generated LINQ-to-SQL type based on an email table. Since the e-mail table is just one of several objects that belong to the domain model class (for example, User), it is ideal to create a User model class and use the Validation Application Block to validate the properties. In other words, I would like to use this:

public class User
{
    private Email emailEntity;

    [EmailAddressValidator]
    public string EmailAddress
    {
        get { return emailEntity.Address; }
        set { emailEntity.Address = value; }
    }
}

      

So, if I change my database schema and the changes hit my generated LINQ-to-SQL classes, I don't have those orphan partial classes (like the Email partial class). I also want to take advantage of the attributes of the Application Validation block, so I don't need to maintain a set of regexes like the NerdDinner tutorial did. Also, the user as a domain class will be a functional unit in the domain, not email and other objects, for creating view models, rendering views, etc. However, there is no way to capture the validation call without doing something like:

public abstract class DomainEntity
{
    public event EventHandler Validation(object sender, EventArgs args);
    protected void OnValidation()
    {
        if (this.Validate != null)
            this.Validate(this, EventArgs.Empty);
    }
}

public partial class Email
{
    partial void OnValidate(ChangeAction action)
    {
        this.OnValidation();
    }
}

      

And then connecting the user to this event and handle all the checks in User. Will this work well with the Application Validation block? How do I perform validation on aggregated domain classes like User in a reasonable way?

+2


source to share


2 answers


Treating validation as a service rather than a subject's responsibility will allow you to decouple the implementation of validation from determining what is valid and include validation in an explicit operation rather than an implicit one (managed by L2S).



Take a look at the good validation for .net ( http://www.codeplex.com/FluentValidation ) for a good implementation of this approach.

+1


source


Check out this article . It explains how to validate LINQ to SQL using the Microsoft Validator Application Box.



As the article says, the trick to using the validator application block is to use configuration-based validation instead of attribute-based validation. Since entities are generated, using an attribute-based approach is nearly impossible.

0


source







All Articles