I would like to start a debate on traditional repositories versus one built on the UnitOfWork pattern.
In a traditional repository, we wrap inserts, updates and deletes in a transaction, but selects don’t really need them. In addition, nhibernate configuration is typically done once per application due to BuildSessionFactory being rather expensive. We often have several repositories of this type (one per aggregate chain). We also need to have projected, ahead of time, exactly what kinds of queries we’ll need in order to build the interfaces and concretes correctly.
In a single UnitOfWork repository we have the ability to manage both the current session and transaction, perform several operations, and then commit any changes all at once. In such a repository we may opt to put our configuration in the constructor since (typically speaking) no more than one Action is called per request anyway, initializing it in the application doesn’t seem like much of an overall gain in speed.
I must admit, I’m very temped to use the UnitOfWork pattern, as the following code looks really nice to me:
using (IUnitOfWork worker = new UnitOfWork())
{
// session and transaction are now both set
// save changes to three items
worker.SaveOrUpdate(item1);
worker.SaveOrUpdate(item2);
worker.SaveOrUpdate(item3);
// grab a fourth
var item4 = worker.Criteria<Foo>().Add(Expression.Eq("title", title)).UniqueResult<Foo>();
// delete the fourth
worker.Delete(item4);
// all pending operations are commited or rolled back as a single unit (if one fails, all are rolled back), and then disposed, along with the session
}
My proposed UnitOfWork class is rather simple. It implements IDisposable where I use a try-catch-finally in Dispose() to attempt a tx.Commit(), doing a tx.Rollback on failure, and a cleaning everything up in the finally clause. It also exposes common things like SaveOrUpdate, Delete, GetAll, Get, and even a Critera<T>() for custom on-the-spot queries.
So what are your thoughts on this? I’d really like to hear about your experience with this pattern.