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.
NHibernate
using NuGet Package Manager Console.Global.asax
.Global.asax.cs
, add these using statements:using NHibernate; using NHibernate.Cfg; using NHibernate.Context;
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.
NH4CookbookHelpers
using NuGet Package Manager Console.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"); }); }
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.hibernate-configuration
section of web.config
, add the current_session_context_class
property with a value of web
.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(); }
Application_BeginRequest
method, add the following code:protected void Application_BeginRequest(object sender, EventArgs e) { var session = SessionFactory.OpenSession(); CurrentSessionContext.Bind(session); }
Application_EndRequest
method, add the following code:protected void Application_EndRequest(object sender, EventArgs e) { var session = CurrentSessionContext.Unbind(SessionFactory); session.Dispose(); }
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.
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.
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:
3.145.8.153