Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the right way to ensure your Repository and UnitOfWork class share the same nhibernate session object?

I am having issues editing and deleting objects and i think its because i am not sharing the same session objects between my repository classes and my unitofwork class. I am trying to find some document on the best way to wire this up so I share the same session object.

I am using ninject as my IOC container in the mvc website.

like image 348
leora Avatar asked Feb 19 '23 00:02

leora


1 Answers

I usually set the session as a dependency of the repository, so Ninject can resolve the dependency (ISession = NHibernate.ISession):

public UserRepository(ISession session)
{
    ...
}

This is how I set the binding:

kernel.Bind<ISession>().ToMethod(x => GetRequestSession()).InRequestScope();

So when a session is required Ninject will call GetRequestSession() to retrieve the session. The function is implemented as follows:

private static ISession GetRequestSession()
        {
            IDictionary httpContextItems = HttpContext.Current.Items;

            ISession session;
            if (!httpContextItems.Contains(MvcApplication.SESSION_KEY))
            {
                // Create an NHibernate session for this request
                session = MvcApplication.SessionFactory.OpenSession();
                httpContextItems.Add(MvcApplication.SESSION_KEY, session);
            }
            else
            {
                // Re-use the NHibernate session for this request
                session = (ISession)httpContextItems[MvcApplication.SESSION_KEY];
            }
            return session;
        }

The NHibernate session is stored in the HttpContext items. This is a key-value collection which can be used to store and share data during the handlng of one request.

The session is created only once per request, and is re-used during the request.

MvcApplication.SESSION_KEY is just a constant string I defined in Global.asax to be able to store and retrieve the session from the HttpContext. Also the session factory is located in global.asax and is created at start-up.

Your unit of work class could also set the ISession as a dependency, so Ninject will resolve this dependency as well and therefore use the same session. On the other hand, you might not need a unit of work class, because NHibernate's implementation of ISession in itself is already a unit of work class.

I'm not sure if this is a best practice, but it works perfectly for me.

like image 80
Robin van der Knaap Avatar answered Apr 07 '23 18:04

Robin van der Knaap