I was thinking the same thing.
Here's what I have:
Code:
public class NHManager : IDisposable
{
private static object _lockDummy = new object();
private NHManager()
{
//read configuration here
_config = new Configuration();
//add the classes in the assembly
_config.AddAssembly("Foundation");
//construct the global factory
_factory = _config.BuildSessionFactory();
}
private Configuration _config = null;
private ISessionFactory _factory = null;
public ISessionFactory SessionFactory
{
get { return _factory; }
}
private static NHManager _instance = null;
public static NHManager Instance
{
get
{
//lock for threadsafe operation
lock(_lockDummy)
{
if(_instance == null)
{
_instance = new NHManager();
}
}
return _instance;
}
}
I actually JUST now placed that lock on the singelton to secure threadsafety for the factory. This may alleviate some of my concerns.
Here's the HttpModule:
Code:
public class NHSessionModule : IHttpModule, System.Web.SessionState.IReadOnlySessionState
{
private ISession _session = null;
private const string NHSESSION = "NHSESSION";
public NHSessionModule()
{
}
#region IHttpModule Members
public void Init(HttpApplication application)
{
//hook events
application.PreRequestHandlerExecute += new EventHandler(application_PreRequestHandlerExecute);
application.PostRequestHandlerExecute += new EventHandler(application_PostRequestHandlerExecute);
}
public void Dispose()
{
}
#endregion
private void application_PreRequestHandlerExecute(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
Logger.Log("NHSessionModule", string.Format("BeginRequest for {0} : Getting ISession", app.Request.Url.ToString()));
//check to see if there is a floating session we can use
if( app.Context.Session != null &&
app.Context.Session[NHSESSION] != null)
{
Logger.Log("Floating session found, loading");
//load it from session instead of creating a new one
_session = app.Context.Session[NHSESSION] as ISession;
if(! _session.IsConnected)
{
Logger.Log("Session was disconnected. Reconnecting...");
_session.Reconnect();
}
}
else
{
//check for local session
if(_session == null)
{
//create new session from our NH Manager class
Logger.Log("Creating ISession from SessionFactory");
_session = NHManager.Instance.SessionFactory.OpenSession();
}
else
{
Logger.Log("NHSessionModule", "Using previous ISession");
if(! _session.IsConnected)
{
Logger.Log("NHSessionModule", "Reconnecting previous session");
_session.Reconnect();
}
}
}
//add to context for future requests
Logger.Log("Adding current session to Context");
app.Context.Items.Add(NHSESSION, _session);
}
private void application_PostRequestHandlerExecute(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
try
{
Logger.Log("NHSessionModule", string.Format("End Request for {0}: handling ISession", app.Request.Url.ToString()));
//if session is floating, disconnect it, but leave it floating
if( app.Context.Session != null &&
app.Context.Session[NHSESSION] != null)
{
Logger.Log("NHSessionModule", "Floating session found, disconnecting and leaving it floating.");
((ISession)app.Context.Session[NHSESSION]).Disconnect();
return;
}
//otherwise, get the session from the context
_session = app.Context.Items[NHSESSION] as ISession;
//flush and disconnect it
Logger.Log("NHSessionModule", "Flushing, disconnecting, and closing ISession");
if(_session != null)
{
if(_session.IsConnected)
{
Logger.Log("NHSessionModule", "Session was connected, flushing and disconnecting");
_session.Flush();
_session.Disconnect();
}
if(_session.IsOpen)
{
Logger.Log("NHSessionModule", "Session was open, closing");
_session.Close();
}
}
Logger.Log("NHSessionModule", "Dereferencing Context item");
//dereference context
app.Context.Items[NHSESSION] = null;
}
catch(NullReferenceException nullRefExc)
{
Logger.LogException("NHSessionModule", "Error trying to end the request: probably no session object", nullRefExc);
}
}
}
The stuff about "Floating Sessions" up there isn't currently being used... I couldn't get it to work properly.