HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Unit of Work / Repository nHibernate

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
nhibernaterepositoryworkunit

Problem

I have a Unit of Work / Repository pattern in place to abstract away some nHibernate. Most examples I've seen though use the pattern a little differently.

In particular, in the constructor for UnitOfWork, most examples start the transaction immediately and have one transaction per unit of work. Whereas I created a BeginTransaction method so I can do something like,

using(var tx = unitOfWork.BeginTransaction())
{
    // Do transactional things here!
}


Is there a reason why others instantiate their transaction per unit of work?

IUnitOfWork

public interface IUnitOfWork : IDisposable
{
    IReadWriteRepository GetRepository() where TEntity : class;
    void Commit();
    void Rollback();
}


UnitOfWork

```
public class UnitOfWork : IUnitOfWork
{
private readonly ISessionFactory _sessionFactory;
private ITransaction _transaction;
private Dictionary _repositories;

public ISession Session { get; private set; }

public UnitOfWork(ISessionFactory sessionFactory)
{
_sessionFactory = sessionFactory;
Session = _sessionFactory.OpenSession();
}

public IReadWriteRepository GetRepository() where TEntity : class
{
foreach (var key in _repositories.Keys)
{
if (key == typeof(TEntity))
{
return _repositories[typeof(TEntity)] as IReadWriteRepository;
}
}

var repository = new Repository(Session);
_repositories.Add(typeof(TEntity), repository);
return repository;
}

public ITransaction BeginTransaction()
{
if(_transaction != null)
{
throw new InvalidOperationException("Cannot have more than one transaction per session.");
}
_transaction = Session.BeginTransaction(IsolationLevel.ReadCommitted);
return _transaction;
}

public void Commit()
{
if(!_transaction.IsActive)
{
throw new InvalidOperationException("Can

Solution

Is there a reason why others instantiate their transaction per unit of work?

Yes, this is because more often than not, a unit of work is a single transaction, either it's committed, or it's not.

Committing part of the work and not other parts, is not really a single unit.

Additionally, Unit of Work is used frequently in web development where one unit = one http request, many people inject a unit of work into the http context in some way to allow a single post/get to commit or fail.

Also, looking at your code, you only use one repository per unit of work, this doesn't seem quite right, what if you wanted to do more than one thing / operate on more than one type?

The unit of work is supposed to wrap up several actions (such as several repository operations) and then either commit all or rollback. Your current implementation doesn't seem to offer you that particularly.

Context

StackExchange Code Review Q#55127, answer score: 4

Revisions (0)

No revisions yet.