OK, here's what I have. I have two classess, the module and a session factory class
first the module:
Code:
using System;
using System.Web;
using NHibernate;
namespace Web.Handlers
{
public class SessionHandler : IHttpModule
{
private static readonly string KEY = "NHibernateSession";
SessionFactory sf;
public void Init(HttpApplication context)
{
context.BeginRequest += new EventHandler(context_BeginRequest);
context.EndRequest += new EventHandler(context_EndRequest);
sf = new SessionFactory();
}
public void Dispose()
{
sf = null;
}
private void context_BeginRequest(object sender, EventArgs e)
{
HttpApplication application = (HttpApplication)sender;
HttpContext context = application.Context;
context.Items[KEY] = null;
if(!sf.Session.IsConnected)
{
sf.OpenSession();
}
context.Items[KEY] = sf.Session;
}
private void context_EndRequest(object sender, EventArgs e)
{
HttpApplication application = (HttpApplication)sender;
HttpContext context = application.Context;
ISession session = context.Items[KEY] as ISession;
if (session != null)
{
try
{
session.Flush();
session.Close();
}
catch {}
}
context.Items[KEY] = null;
}
public static ISession CurrentSession
{
get
{
HttpContext currentContext = HttpContext.Current;
ISession session = currentContext.Items[KEY] as ISession;
SessionFactory lsf;
if (session == null)
{
lsf = new SessionFactory();
session = lsf.Session;
currentContext.Items[KEY] = session;
}
if(!session.IsConnected)
{
session.Reconnect();
}
return session;
}
}
}
}
now the sessionfactory
Code:
using System;
using NHibernate;
using NHibernate.Cfg;
using System.Collections;
using NHibernate.Expression;
namespace Web.Handlers
{
/// <summary>
/// Summary description for SessionFactory.
/// </summary>
public class SessionFactory
{
Configuration config;
ISessionFactory factory;
private ISession session;
public SessionFactory()
{
config = new Configuration();
config.AddAssembly("MyAssembly");
factory = config.BuildSessionFactory();
OpenSession();
}
~SessionFactory()
{
if (null != session)
{
session.Dispose();
}
if (null != factory)
{
factory.Close();
}
}
public void OpenSession()
{
session = factory.OpenSession(new MyInterceptor());
}
public ISession Session
{
get
{
return session;
}
}
}
}
I didn't have the context.BeginRequest in the handler originally (based on the code on the blog) and it would work most of the time, sometimes the first access of objects via Nhibernate would fail, then work fine on second call, or an action (say navigating to a page calling the handler) would work 4 times, then die on the fifth (either the Object reference not set error, or sometimes a session is closed error).
It now works 100%, I can even stop on a page, leave it overnight, and resume the next morning without error (so I know the session is long killed).
Hope this helps
Mark