我想在我的ASP.NET MVC 2應用程序中使用NHibernate的上下文會話,但我很難找到如何正確執行此操作的指導。ASP.NET MVC中的NHibernate上下文會話
我對每個請求的Session有興趣。
我想在我的ASP.NET MVC 2應用程序中使用NHibernate的上下文會話,但我很難找到如何正確執行此操作的指導。ASP.NET MVC中的NHibernate上下文會話
我對每個請求的Session有興趣。
請讓我知道,如果我這樣做是正確的。以下是我想出了:
的Global.asax
public class MvcApplication : NinjectHttpApplication
{
public MvcApplication()
{
NHibernateProfiler.Initialize();
EndRequest += delegate { NHibernateHelper.EndContextSession(Kernel.Get<ISessionFactory>()); };
}
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("favicon.ico");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
protected override void OnApplicationStarted()
{
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
}
protected override IKernel CreateKernel()
{
StandardKernel kernel = new StandardKernel();
kernel.Load(AppDomain.CurrentDomain.GetAssemblies());
return kernel;
}
}
NHibernateHelper
public class NHibernateHelper
{
public static ISessionFactory CreateSessionFactory()
{
var nhConfig = new Configuration();
nhConfig.Configure();
return Fluently.Configure(nhConfig)
.Mappings(m =>
m.FluentMappings.AddFromAssemblyOf<Reservation>()
.Conventions.Add(ForeignKey.EndsWith("Id")))
#if DEBUG
.ExposeConfiguration(cfg =>
{
new SchemaExport(cfg)
.SetOutputFile(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "schema.sql"))
.Create(true, false);
})
#endif
.BuildSessionFactory();
}
public static ISession GetSession(ISessionFactory sessionFactory)
{
ISession session;
if (CurrentSessionContext.HasBind(sessionFactory))
{
session = sessionFactory.GetCurrentSession();
}
else
{
session = sessionFactory.OpenSession();
CurrentSessionContext.Bind(session);
}
return session;
}
public static void EndContextSession(ISessionFactory sessionFactory)
{
var session = CurrentSessionContext.Unbind(sessionFactory);
if (session != null && session.IsOpen)
{
try
{
if (session.Transaction != null && session.Transaction.IsActive)
{
// an unhandled exception has occurred and no db commit should be made
session.Transaction.Rollback();
}
}
finally
{
session.Dispose();
}
}
}
}
NHibernateModule
public class NHibernateModule : NinjectModule
{
public override void Load()
{
Bind<ISessionFactory>().ToMethod(x => NHibernateHelper.CreateSessionFactory()).InSingletonScope();
Bind<ISession>().ToMethod(x => NHibernateHelper.GetSession(Kernel.Get<ISessionFactory>()));
}
}
很乾淨的例子+1 – 2014-09-25 19:01:31
我們的做法與bigglesby略有不同,我不是說他的錯誤,或者我們的完美。
在我們在應用程序啓動在Global.asax我們:
...
protected void Application_Start() {
ISessionFactory sf =
DataRepository
.CreateSessionFactory(
ConfigurationManager
.ConnectionStrings["conn_string"]
.ConnectionString
);
//use windsor castle to inject the session
ControllerBuilder
.Current
.SetControllerFactory(new WindsorControllerFactory(sf));
}
...
我們DataRepository我們: 注:(這是不是一個庫 - 我的設計錯誤:壞的名字 - ,它更象你NHibernateHelper,我想它更是某種NH配置包裝的...)
....
public static ISessionFactory CreateSessionFactory(string connectionString) {
if (_sessionFactory == null){
_sessionFactory = Fluently.Configure()
.Database(MsSqlConfiguration ...
...
//custom configuration settings
...
cfg.SetListener(ListenerType.PostInsert, new AuditListener());
})
.BuildSessionFactory();
}
return _sessionFactory;
}
....
與會話工廠的事,是你不想生成/建立一個在每次請求。 DataRepository充當單例,確保會話工廠只創建一次,並且在應用程序啓動時。在我們的基礎控制器中,我們使用WindosrCastle將會話或sessionfactory注入到控制器(某些控制器不需要數據庫連接,因此它們來自「無數據庫」基本控制器)。我們WindsorControllerFactory我們:
...
//constructor
public WindsorControllerFactory(ISessessionFactory) {
Initialize();
// Set the session Factory for NHibernate
_container.Register(
Component.For<ISessionFactory>()
.UsingFactoryMethod(
() => sessionFactory)
.LifeStyle
.Transient
);
}
private void Initialize() {
_container = new WindsorContainer(
new XmlInterpreter(
new ConfigResource("castle")
)
);
_container.AddFacility<FactorySupportFacility>();
// Also register all the controller types as transient
var controllerTypes = from t in Assembly.GetExecutingAssembly().GetTypes()
where typeof(IController).IsAssignableFrom(t)
select t;
foreach (var t in controllerTypes) {
_container.AddComponentLifeStyle(t.FullName, t, LifestyleType.Transient);
}
}
....
有了這個設置,每個請求都會產生一個NHibernate的會議,並與我們的設計,我們也能有不產生會話控制器。那目前它是如何爲我們工作的。
我還可以說我發現NHProf在嘗試配置或調試我們遇到的問題時非常有用。
我沒有注意到你需要ICurrentSessionContext,認爲任何「每個請求的會話」都可以。 – queen3 2010-09-09 20:46:12