Repository vs. UnitOfWork [closed]


My current point of view is that repository should contain entity-specific modification methods like Add, Delete, etc. and UnitOfWork should contain just methods that are relevant to it in general like Commit (also known as SaveChanges, SubmitChanges) and Rollback (also known as ClearChanges). But Martin Fowler in his <a href="http://martinfowler.com/eaaCatalog/unitOfWork.html" rel="nofollow">article</a> about UnitOfWork suggests to add all modification methods to UnitOfWork.

So which way is better now, in the world of EF and NHibernate?

<strong>Update.</strong> I should note that even with my preferable approach finally all modifications through repository go into UnitOfWork which is built into EF Context or NHibernate Session. And my UnitOfWork is more like UnitOfWorkManager (which manages internal ORM UnitOfWork).


In NHibernate world main functionality of UnitOfWork in implemented by ISession. ISession keeps track of what has changed and you do not need to have methods like RegisterClean or RegisterDirty. For a larger projects it is useful to hide ISession by using your own class that can be called UnitOfWork. For example:

public class UnitOfWork { private readonly ISession _session; public void BeginTransaction(); public void Commit(); public void Rollback(); public IRepositoryFactory AllRepositories; }

The advantage of hiding ISession from application code is that this code will not reference NHibernate directly which enforces better layering. In other words it will be harder for application layer to start using NHibernate API directly, bypassing data access layer.

The repository itself will contain methods for adding new objects and possibly deleting:

public interface IOrdersRepository { public IList<Order> FindPending(); public void AddNew(Order order); public void Delete(Order order); }


These are two different patterns.

Repository is responsible for abstracting the data storage from upper layers, whilst Unit Of Work is responsible for business transaction management. Repository allows you to substitute storage without changing the code - you can work with text file, XML, database - whatever. UoW gives you an opportunity to control and trace changes to the entities and persist all of the changes of one business transaction at once.

Both EF and NH support UoW by default so you don't need to reimplement it yourself. Still you would want to write your own repository pattern, as these ORMs do not provide it out of the box.

UoW on top of NH and EF is unnecessary level of abstraction and may be viewed as an antipattern.

In that article Fowler does not actually suggest to add responsibility of data manipulations to UoW. What he is saying is you can <em>track</em> changes to objects and flush/rollback them as needed.