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.