Setting up session-per-web request

Due to its simplicity, the most common pattern used in web applications for managing NHibernate sessions is session-per-request. In this recipe, we'll show you how to set up the session-per-request pattern using NHibernate's contextual sessions feature.

Getting ready

  1. Create a new ASP.NET web forms or ASP.NET MVC application.
  2. Add a reference to NHibernate using NuGet Package Manager Console.
  3. If it doesn't exist already, add a new global application class Global.asax.
  4. In Global.asax.cs, add these using statements:
    using NHibernate;
    using NHibernate.Cfg;
    using NHibernate.Context;
  5. Create a static property named SessionFactory:
    public static ISessionFactory SessionFactory { get; private set; }

Now you have two choices. You can either use the companion library, NH4CookbookHelpers to set up the base configuration or set everything up manually.

Option 1: Using the companion library

  1. Add a reference to NH4CookbookHelpers using NuGet Package Manager Console.
  2. In the Application_Start method in Global.asax.cs, add the following code:
    protected void Application_Start(object sender, EventArgs e)
    {
      SessionFactory=ProductModel
        .CreateExampleSessionFactory(true, conf => {
        conf.SetProperty("current_session_context_class", "web");
      });
    }

Option 2: Manual setup

  1. In the web.config file, set up the NHibernate and log4net configuration sections. Refer to the Configuring NHibernate with App.config recipes in Chapter 1, The Configuration and Schema.
  2. In the hibernate-configuration section of web.config, add the current_session_context_class property with a value of web.
  3. In the Application_Start method in Global.asax.cs, add the following code:
    protected void Application_Start(object sender, EventArgs e)
    {
      var nhConfig = new Configuration().Configure();
      SessionFactory = nhConfig.BuildSessionFactory();
    }

How to do it…

  1. In the Application_BeginRequest method, add the following code:
    protected void Application_BeginRequest(object sender, EventArgs e)
    {
      var session = SessionFactory.OpenSession();
      CurrentSessionContext.Bind(session);
    }
  2. In the Application_EndRequest method, add the following code:
    protected void Application_EndRequest(object sender, 
    EventArgs e)
    {
      var session = CurrentSessionContext.Unbind(SessionFactory);
      session.Dispose();
    }

How it works…

In web applications, it's common to use a session for each web request. We open the session when the request begins and close it when the request ends.

NHibernate's contextual session feature allows a session to be associated with application-specific scope that approximates a single unit of work. This context is configured with the current_session_context_class property, which specifies an implementation of NHibernate.Context.ICurrentSessionContext. In this case, we'll associate it with the web request. web is the short name for NHibernate.Context.WebSessionContext.

Even with contextual sessions, NHibernate does not open, close, or dispose the session for us. We have to associate and dissociate a session with the current web request using the CurrentSessionContext.Bind and Unbind methods.

There's more…

To get the NHibernate session for the current web request, we use SessionFactory.GetCurrentSession(). In our example web application, it might look something similar to this:

Guid productId = new Guid(Request["id"]);
Product product;
var session = Global.SessionFactory.GetCurrentSession();
using (var tran = session.BeginTransaction())
{
  product = session.Get<Product>(productId);
  tran.Commit();
}
Page.Title = product.Name;
Label1.Text = product.Name;
Label2.Text = product.Description;

This naive example fetches a product from the database and displays the name and description to the user. In a production-worthy application, we would probably use dependency injection rather than directly access the singleton.

Note

NHibernate sessions are extremely lightweight and cheap to make. Simply opening a session doesn't open a database connection. NHibernate makes every effort to avoid or delay opening of a connection. On the other hand, NHibernate goes through great effort to create the session factory. You should only create one session factory for the entire lifecycle of the application.

There are many implementations of session-per-request using inversion of control containers and even HTTP modules. Some use contextual sessions, while others manage the session without NHibernate's help. A complete session-per-request implementation has the following four characteristics:

  • Create the one and only session factory when the application starts
  • Open a session when the web request begins
  • Close the session when the request ends
  • Provide a standard way to access the current session throughout the data access layer

See also

  • Creating a session ASP.NET MVC action filter
  • Creating a transaction ASP.NET MVC action filter
  • Setting up session-per-presenter
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.8.153