Refactoring insight: repositories gone wild!

Here’s a snippet from my prototype NHibernateRepository<T> I mentioned the other day. Can you see what I’ve done wrong here?

public abstract class NHibernateRepository<T>
{
    protected ISession unitOfWork;
    protected IEntityValidator<T> validator;

    protected NHibernateRepository(ISession unitOfWork,
        IEntityValidator<T> validator)
    {
        if (unitOfWork == null)
            throw new ArgumentNullException("unitOfWork");
        if (validator == null)
            throw new ArgumentNullException("validator");

        this.validator = validator;
        this.unitOfWork = unitOfWork;
    }

    protected virtual void Validate(T item)
    {
        IEnumerable<RuleViolation> ruleViolations =
            this.validator.GetAllRuleViolations(item);

        if (ruleViolations.Count() == 0)
            return;

        string message = String.Format(
            "The {0} '{1}' could not be persisted because it failed validation.",
            typeof(T).Name, item);

        throw new RuleViolationException(message, ruleViolations);
    }

    public virtual void Save(T item)
    {
        Validate(item);
        using (ITransaction transaction = this.unitOfWork.BeginTransaction())
        {
            this.unitOfWork.SaveOrUpdate(item);
            transaction.Commit();
        }
    }

    // ...
}

See that Validate() method? It’s very clever, automatically checking entities are valid before it commits them to the database. Unfortunately, validating entities is not the responsibility of a repository. This is a big fat violation of the single responsibility principle (SRP), and should be moved to a higher-level domain service instead.

January 21, 2009

Leave Your Comment

Your email will not be published or shared. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>