Evil Validation pattern

We want to use Evil (Entity Validation Library) do DTO validation on UI layer. I then changed Jimmy’s pattern to use the same style as Evil. One big benefit is removing the out keyword in method, Igloo coder said using out is a procedural code smell.

Some principals for validation:

  1. Domain entity should always be valid, even right after new(). ctor has to take all required fields to make a fresh created entity valid.
  2. Never try to valid the entity retrieve database, instead, a data clean up should be done before app released. Or create a cc.net routine to constantly check data on those shared database?
  3. Never try to positionally make a entity invalid, always try valid before making changes, not after then rollback.

       // in Organization
        public void AddEmail(Email emailToAdd)
        {
            // Before add, check duplication
            IEnumerable<string> brokenRules;

            var emailValidator = new EmailValidator(emailToAdd);
            if (!emailValidator.IsValid()) throw new ValidationException(emailValidator.ValidationErrors); 

            var dupValidator = new NoDuplicateEmailAddressValidator(_emails, emailToAdd);
            if (!dupValidator.IsValid()) throw new ValidationException(dupValidator.ValidationErrors); 

            _emails.Add(emailToAdd);
        }

    public class EmailValidator : BaseValidator
    {
        public EmailValidator(Email email)
        {

            if (new SomethingWentWrongSpec.IsSatidsiedBy(entity)
                AddValidationError("Email address has something went wrong. ");

        }

    public class BaseValidator
    {
        private IList<string> _validationErrors = new List<string>();
        public IEnumerable<string> ValidationErrors
        {
            get { return _validationErrors; }
        }

        public bool IsValid()
        {
            return ValidationErrors.Count() == 0;
        }

        protected void AddValidationError(string error)
        {
            _validationErrors.Add(error);
        }    

        protected void AddValidationErrors(IEnumerable<string> errors)
        {
            _validationErrors.Union(errors);
        }
    }
    }

I tried Specification pattern in Domain entities, it’s neat for its nice re-wrote if condition, but the native Specification can’t process error messages, so I just use the validator directly in Domain entity class.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s