asp.netnhibernatedependency-injectionrepository-patternisession

How to pass unit of work container into constructor of repository using dependency injection


I'm trying to work out how to complete my implementation of the Repository pattern in an ASP.NET web application.

At the moment, I have a repository interface per domain class defining methods for e.g. loading and saving instances of that class.

Each repository interface is implemented by a class which does the NHibernate stuff. Castle Windsor sorts out the DI of the class into the interface according to web.config. An example of an implemented class is provided below:

  public class StoredWillRepository : IStoredWillRepository
  {
    public StoredWill Load(int id)
    {
      StoredWill storedWill;
      using (ISession session = NHibernateSessionFactory.OpenSession())
      {
        storedWill = session.Load<StoredWill>(id);
        NHibernateUtil.Initialize(storedWill);
      }
      return storedWill;
    }

    public void Save(StoredWill storedWill)
    {
      using (ISession session = NHibernateSessionFactory.OpenSession())
      {
        using (ITransaction transaction = session.BeginTransaction())
        {
          session.SaveOrUpdate(storedWill);
          transaction.Commit();
        }
      }
    }
  }

As pointed out in a previous thread, the repository class needs to accept an unit of work container (i.e. ISession) rather than instantiating it in every method.

I anticipate that the unit of work container will be created by each aspx page when needed (for example, in a property).

How do I then specify that this unit of work container instance is to be passed into the constructor of StoredWillRepository when Windsor is creating it for me?

Or is this pattern completely wrong?

Thanks again for your advice.

David


Solution

  • Technically, the answer to my question is to use the overload of container.Resolve which allows you to specify the constructor argument as an anonymous type:

    IUnitOfWork unitOfWork = [Code to get unit of work];
    _storedWillRepository = container.Resolve<IStoredWillRepository>(new { unitOfWork = unitOfWork });
    

    But let's face it, the answers provided by everyone else have been much more informative.