Question

I have a repository pattern setup using NHibernate. The base class looks like this:

public interface IUnitOfWork : IDisposable
{
    void Commit();
    void Rollback();
}

// generic NHibernate implementation of IUnitOfWork here

public class NHibernateRepositoryBase<T> : IRepository<T>
{
    private NHibernateUnitOfWork _unitOfWork;

    public NHibernateRepositoryBase(NHibernateUnitOfWork unitOfWork)
    {
        _unitOfWork = unitOfWork;
    }
    public T Get(object id)
    {
        return _unitOfWork.Session.Get<T>(id);
    }

    // ...
}

As you can see, I'm allowing the unit of work to be populated via the constructor (using StructureMap). I'm populating the repository objects on my ASP.NET web services like so:

[WebService(Namespace = "...")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class ModuleService : System.Web.Services.WebService
{
    public IUserAccountRepository UserAccountRepo { get; set; }

    public ModuleService()
    {
        // tell IoC to inject properties
        ObjectFactory.BuildUp(this);
    }

    // ...
}

As you may be able to deduce, my problem is that by way of design, I've now lost control of the lifecycle of the unit of work. Previously, I made the unit of work a context sensitive object and the repository would obtain a reference to it via something like:

public class NHibernateRepositoryBase<T> : IRepository<T>
{
    public T Get(object id)
    {
        return NHibernateUnitOfWork.GetCurrent().Session.Get<T>(id);
    }

    // ...
}

This previous design allowed me to control the life cycle of the unit of work in my code by creating the unit of work from a UnitOfWorkFactory within a using statement. I was trying to put more of the work in the hands of the IoC container, but I think I actually took a step backwards. What are your thoughts on either implementation?

Was it helpful?

Solution

It is usually a good thing to let your IoC container handle as much as possible. On the web a unit of work pattern usually get initialized at the start of the request and committed at the end (rolled back if there is any exceptions). This way your repository will take a ISession in the constructor instead of the unitofwork. This way, your repository will not have to deal with committing or anything and that will be handled automatically for you.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top