Ryan Lanciaux

Random programming blog.

NHibernate Session Per Request

A little earlier on, I had posted a simple example of NHibernate in an MVC application as well as some initial questions I had about NHibernate Session management. In response to my question, Matt Hinze mentioned that the session should be transparent to the controller and posted some links to various articles explaining how to achieve this. I finally had a chance to play around with this type of session management and spent most of my time looking through Billy McCafferty's NHibernate Best practices on CodeProject. As I've mentioned before, I'm very new to NHibernate so some of the things I'm doing may not be ideal.

HTTP Module

First off, I created an HTTP module; this is where the session will be opened and closed (by accessing the session manager class). You'll notice on the Init that event handlers have been added. I'm using the same session manager class that I was using in my last example, however, now it's being initialized / closed here (rather than in each controller action).

    public class SessionModule : IHttpModule

    {

        private ISession _session;

 

        public void Init(HttpApplication context)

        {

            context.BeginRequest += new EventHandler(OpenSession);

            context.EndRequest += new EventHandler(CloseSession);

        }

 

        private void OpenSession(object sender, EventArgs e)

        {

            _session = SessionManager.GetCurrentSession();

        }

 

        private void CloseSession(object sender, EventArgs e)

        {

            _session.Flush();

            _session.Close();

        }

 

        public void Dispose()

        {

            _session = null;

        }

    }


Next, I added this class to the HttpModules section of the web.config

<add name="SessionModule" type="ProductModel.Session.SessionModule"/>

Controller Code

Finally, since the NHibernate Session is being created / closed in the HTTP Module, I no longer have to use the using statement in every controller. Instead, I'm just setting a ISession = to the SessionManagers Current session.

   public ActionResult AddProduct(string ID)

   {

       ISession session = SessionManager.GetCurrentSession();

       return RenderView("AddProduct",

           new SimpleProductRepository(session).List());

   }

Wrapping Up

There's still a bit more I want to explore with this method of Session Management (maybe transactions). Also I would be interested to test out the threading / performance implications of going this route. I've updated the code on my assembla site. If you're interested, you can check it out here http://svn2.assembla.com/svn/NHibernateTest/ (keep in mind it's demo code – not anything remotely resembling anything I would use in production). I would really appreciate any suggestions / feedback that you may have!