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
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();
}
精彩评论