2

I have gotten into a problem with my project. I am using a generic repository with structure map together with Fluent NHibernate. Everything works rather well, but when it comes to transactions and session management I have really no clue what to do. I have looked around for answers but I cant really find anything that fit my needs.

What I do in my application is that I let structure map instantiate a repository class when it gets a request for it, like so:

internal class RepositoryRegistry : Registry
{
    public RepositoryRegistry()
    {
        For<IRepository<User>>().Use<Repository<User>>();
        For<IRepository<Tasks>>().Use<Repository<Tasks>>();
    }
}

internal class NHibernateRegistry : Registry
{
    public NHibernateRegistry()
    {
        For<ISessionFactory>()
            .Singleton()
            .Use(() => new NHibernateSessionFactory().GetSessionFactory());

        For<ISession>()
            .Singleton()
            .Use(x => x.GetInstance<ISessionFactory>().OpenSession());
    }
}

public interface IRepository<T>
{
    T GetById(int id);

    void SaveOrUpdate(T entity);

    IList<T> GetAll();

    IQueryable<T> Linq();

    void Add(T entity);

}

Edit: I have concluded what I need. I wan't to use the unit of work pattern along with structure map, but I also want to have some kind of repository wrapper which can be accessed through a unit of work.

Thanks, James Ford

James Ford
  • 949
  • 4
  • 12
  • 25

1 Answers1

1

I think that you are looking for the Unit Of Work pattern, where the transaction life time is controlled by a unit of work that you inject into the Repostories/Services.

See this answer for a sample implementation of a UoW with NHibernate and StructureMap.

Edit:

Provided you have implemented a Unit of Work and a generic repository you would basically use them by:

1) Mapping them in structure map:

c.For(typeof(IRepository<>)).Use(typeof(Repository<>));
c.For<IUnitOfWork>().Use<UnitOfWork>();

2) Having the Controller accept a Repository(or a Service encapsulating the repository; this approach is often preferred) and the UnitOfWork:

public class MyController
{
  public MyController(IRepository<MyEntity> repository, IUnitOfWork uow)
  {
     _repository = repository;
     _unitOfWork = uow;
  }
}

This of course also requires that you have created a custom ControllerFactory.

3) Using the Unit of Work and Repository in the controller action:

public ViewResult MyAction(MyEntity entity)
{
  _repository.Save(entity);
  _unitOfWork.Commit();
  return View();
} 
Community
  • 1
  • 1
PHeiberg
  • 29,411
  • 6
  • 59
  • 81
  • Yes it's what i'm looking for. I have peaked at the unit of work pattern before, but I cant seem to understand how till will work with my generic repositories. – James Ford Mar 26 '11 at 00:51
  • Yeah your edit helped me. What I came up with right now is that I access my repositories through a uow. So I only map like For().Use(); and let the controllers access IUnitOfWork. Then I added method public Repository RepositoryFor() where TEntity : class, that will send the session to the repository class so I can access my repositories through a uow. I dont know if this is bad or not but it works. – James Ford Mar 27 '11 at 11:33