NHibernate Session Management(One per request)
最近在学习NHibernate,发现有2种方式 实现
1.SessionManager.cs
View Code
public sealed class SessionManager
{
private const string CurrentSessionKey = "nhibernate.current_session";
private static readonly ISessionFactory sessionFactory;
public static Configuration CurrentConfig { get; set; }
static SessionManager()
{
if (sessionFactory == null)
{
var cfg = new ATMSConfiguration();
var model = AutoMap.AssemblyOf<Users>(cfg);
CurrentConfig = Fluently.Configure()
.Database(MsSqlConfiguration
.MsSql2005
.ConnectionString(c => c.FromConnectionStringWithKey("DbString"))
)
.Mappings(m => m.AutoMappings.Add(model))
.BuildConfiguration();
sessionFactory = CurrentConfig.BuildSessionFactory();
}
}
public static ISession GetCurrentSession()
{
HttpContext context = HttpContext.Current;
ISession currentSession = context.Items[CurrentSessionKey] as ISession;
if (currentSession == null)
{
currentSession = sessionFactory.OpenSession();
context.Items[CurrentSessionKey] = currentSession;
}
return currentSession;
}
public static void CloseSession()
{
HttpContext context = HttpContext.Current;
ISession currentSession = context.Items[CurrentSessionKey] as ISession;
if (currentSession == null)
{
// No current session
return;
}
currentSession.Close();
context.Items.Remove(CurrentSessionKey);
}
public static void CloseSessionFactory()
{
if (sessionFactory != null)
{
sessionFactory.Close();
}
}
}
{
private const string CurrentSessionKey = "nhibernate.current_session";
private static readonly ISessionFactory sessionFactory;
public static Configuration CurrentConfig { get; set; }
static SessionManager()
{
if (sessionFactory == null)
{
var cfg = new ATMSConfiguration();
var model = AutoMap.AssemblyOf<Users>(cfg);
CurrentConfig = Fluently.Configure()
.Database(MsSqlConfiguration
.MsSql2005
.ConnectionString(c => c.FromConnectionStringWithKey("DbString"))
)
.Mappings(m => m.AutoMappings.Add(model))
.BuildConfiguration();
sessionFactory = CurrentConfig.BuildSessionFactory();
}
}
public static ISession GetCurrentSession()
{
HttpContext context = HttpContext.Current;
ISession currentSession = context.Items[CurrentSessionKey] as ISession;
if (currentSession == null)
{
currentSession = sessionFactory.OpenSession();
context.Items[CurrentSessionKey] = currentSession;
}
return currentSession;
}
public static void CloseSession()
{
HttpContext context = HttpContext.Current;
ISession currentSession = context.Items[CurrentSessionKey] as ISession;
if (currentSession == null)
{
// No current session
return;
}
currentSession.Close();
context.Items.Remove(CurrentSessionKey);
}
public static void CloseSessionFactory()
{
if (sessionFactory != null)
{
sessionFactory.Close();
}
}
}
2.SessionModule.cs
View Code
public class SessionModule : IHttpModule
{
private ISession _session;
public void Init(HttpApplication context)
{
context.BeginRequest += new EventHandler(BeginTransaction);
context.EndRequest += new EventHandler(CloseSession);
}
private void CloseSession(object sender, EventArgs e)
{
SessionManager.CloseSession();
}
//Create our session
private void BeginTransaction(object sender, EventArgs e)
{
_session = SessionManager.GetCurrentSession();
}
public void Dispose()
{
_session = null;
}
}
{
private ISession _session;
public void Init(HttpApplication context)
{
context.BeginRequest += new EventHandler(BeginTransaction);
context.EndRequest += new EventHandler(CloseSession);
}
private void CloseSession(object sender, EventArgs e)
{
SessionManager.CloseSession();
}
//Create our session
private void BeginTransaction(object sender, EventArgs e)
{
_session = SessionManager.GetCurrentSession();
}
public void Dispose()
{
_session = null;
}
}
Repository.cs
View Code
public class NHibernateRepository<T> : IRepository<T> where T : class
{
protected ISession session = SessionManager.GetCurrentSession();
public T Get(object id)
{
using (var transaction = session.BeginTransaction())
{
T returnVal = session.Get<T>(id);
transaction.Commit();
return returnVal;
}
}
public void Save(T value)
{
using (var transaction = session.BeginTransaction())
{
session.Save(value);
transaction.Commit();
}
}
public void Update(T value)
{
using (var transaction = session.BeginTransaction())
{
session.Update(value);
transaction.Commit();
}
}
public void Delete(T value)
{
using (var transaction = session.BeginTransaction())
{
session.Delete(value);
transaction.Commit();
}
}
public IList<T> GetAll()
{
using (var transaction = session.BeginTransaction())
{
IList<T> returnVal = session.CreateCriteria<T>().List<T>();
transaction.Commit();
return returnVal;
}
}
/// <summary>
/// Generate DataBaseSchemal
/// </summary>
/// <param name="AreYouSure"></param>
public void GenerateSchema(DBCheck AreYouSure)
{
if (AreYouSure == DBCheck.ThisWillDropMyDatabase)
new SchemaExport(SessionManager.CurrentConfig).Execute(true, true, false);
}
}
{
protected ISession session = SessionManager.GetCurrentSession();
public T Get(object id)
{
using (var transaction = session.BeginTransaction())
{
T returnVal = session.Get<T>(id);
transaction.Commit();
return returnVal;
}
}
public void Save(T value)
{
using (var transaction = session.BeginTransaction())
{
session.Save(value);
transaction.Commit();
}
}
public void Update(T value)
{
using (var transaction = session.BeginTransaction())
{
session.Update(value);
transaction.Commit();
}
}
public void Delete(T value)
{
using (var transaction = session.BeginTransaction())
{
session.Delete(value);
transaction.Commit();
}
}
public IList<T> GetAll()
{
using (var transaction = session.BeginTransaction())
{
IList<T> returnVal = session.CreateCriteria<T>().List<T>();
transaction.Commit();
return returnVal;
}
}
/// <summary>
/// Generate DataBaseSchemal
/// </summary>
/// <param name="AreYouSure"></param>
public void GenerateSchema(DBCheck AreYouSure)
{
if (AreYouSure == DBCheck.ThisWillDropMyDatabase)
new SchemaExport(SessionManager.CurrentConfig).Execute(true, true, false);
}
}
这种HTTPModule方法,会为每个HttpRequest(例如js,img加载) 都会opensession/close session.
另外一种方式是采用DI(依赖注入)的方式Ninject
SessionInjectHelper.cs
View Code
public class SessionInjectHelper {
public static string SESSION_KEY = "NHibernate.ISession";
public static NHibernate.ISession GetRequestSession(IContext Ctx)
{
IDictionary Dict = HttpContext.Current.Items;
NHibernate.ISession Session;
if (!Dict.Contains(SESSION_KEY))
{
// Create an NHibernate session for this request
Session = (Ctx.Kernel.GetService(typeof(SharedConfiguration)) as SharedConfiguration).OpenSession();
Dict.Add(SESSION_KEY, Session);
}
else
{
// Re-use the NHibernate session for this request
Session = (NHibernate.ISession)Dict[SESSION_KEY];
}
return Session;
}
}
public static string SESSION_KEY = "NHibernate.ISession";
public static NHibernate.ISession GetRequestSession(IContext Ctx)
{
IDictionary Dict = HttpContext.Current.Items;
NHibernate.ISession Session;
if (!Dict.Contains(SESSION_KEY))
{
// Create an NHibernate session for this request
Session = (Ctx.Kernel.GetService(typeof(SharedConfiguration)) as SharedConfiguration).OpenSession();
Dict.Add(SESSION_KEY, Session);
}
else
{
// Re-use the NHibernate session for this request
Session = (NHibernate.ISession)Dict[SESSION_KEY];
}
return Session;
}
}
Inject Service
View Code
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IUsersRepository>().To<UserRepository>();
var cfg = new SharedConfiguration();
kernel.Bind<SharedConfiguration>().ToConstant(cfg);
kernel.Bind<NHibernate.ISession>().ToMethod(x => SessionInjectHelper.GetRequestSession(x));
}
{
kernel.Bind<IUsersRepository>().To<UserRepository>();
var cfg = new SharedConfiguration();
kernel.Bind<SharedConfiguration>().ToConstant(cfg);
kernel.Bind<NHibernate.ISession>().ToMethod(x => SessionInjectHelper.GetRequestSession(x));
}
最后在Application_End
View Code
public class MvcApplication : System.Web.HttpApplication
{
public MvcApplication()
{
this.EndRequest += MvcApplication_EndRequest;
}
private void MvcApplication_EndRequest(object sender, System.EventArgs e)
{
if (Context.Items.Contains(SessionInjectHelper.SESSION_KEY))
{
NHibernate.ISession Session = (NHibernate.ISession)Context.Items[SessionInjectHelper.SESSION_KEY];
Session.Close();
Session.Dispose();
Context.Items[SessionInjectHelper.SESSION_KEY] = null;
}
}
{
public MvcApplication()
{
this.EndRequest += MvcApplication_EndRequest;
}
private void MvcApplication_EndRequest(object sender, System.EventArgs e)
{
if (Context.Items.Contains(SessionInjectHelper.SESSION_KEY))
{
NHibernate.ISession Session = (NHibernate.ISession)Context.Items[SessionInjectHelper.SESSION_KEY];
Session.Close();
Session.Dispose();
Context.Items[SessionInjectHelper.SESSION_KEY] = null;
}
}