[英]How can I implement a robust session-per-request pattern in my project, while focusing on information hiding?
I'm currently building an ASP.NET MVC project, with NHibernate as its persistance layer. 我目前正在构建一个ASP.NET MVC项目,NHibernate作为其持久层。
For now, some functionality have been implemented, but only use local NHibernate sessions: each method that accessed the database (read or write) needs to instantiate its own NHibernate session, with the "using()" clause. 目前,已经实现了一些功能,但仅使用本地NHibernate会话:访问数据库(读取或写入)的每个方法都需要使用“using()”子句实例化其自己的NHibernate会话。
The problem is that I want to leverage NHibernate's lazy-loading capabilities to improve the performance of my project. 问题是我想利用NHibernate的延迟加载功能来提高项目的性能。
This implies an open NHibernate session per request until the view is rendered. 这意味着每个请求都会打开一个NHibernate会话,直到呈现视图为止。 Furthermore, simultaneous requests must be supported (multiple Sessions at the same time).
此外,必须支持同时请求(同时多个会话)。
How can I achieve that as cleanly as possible? 我怎样才能尽可能干净地实现这一目标?
I searched the web a little bit and learned about the session-per-request pattern. 我在网上搜索了一下,了解了每个请求的会话模式。 Most of the implementations I saw used some sort of Http* (HttpContext, etc.) object to store the session.
我看到的大多数实现使用某种Http *(HttpContext等)对象来存储会话。 Also, using the Application_BeginRequest/Application_EndRequest functions is complicated, since they get fired for each HTTP request (aspx files, css files, js files, etc.), when I only want to instantiate a session once per request.
此外,使用Application_BeginRequest / Application_EndRequest函数很复杂,因为当我只想为每个请求实例化一次会话时,它们会针对每个HTTP请求(aspx文件,css文件,js文件等)被触发。
The concern that I have is that I don't want my views or controllers to have access to NHibernate sessions (or, more generally, NHibernate namespaces and code). 我担心的是我不希望我的视图或控制器能够访问NHibernate会话(或者更常见的是NHibernate命名空间和代码)。 That means that I do not want to handle sessions at the controller level nor the view one.
这意味着我不想在控制器级别处理会话,也不想在视图级别处理会话。
I have a few options in mind. 我有几个选择。 Which one seems the best?
哪一个看起来最好?
Thank you very much! 非常感谢你!
Well guys, after a few days' work, I finally decided to use the HttpContext.Current.Items to load the session. 好吧,经过几天的工作,我终于决定使用HttpContext.Current.Items来加载会话。
It works great! 它很棒!
Here's how I did it 这就是我做到的
import System.Web
class SessionManager {
public static ISession GetSession()
var session = HttpContext.Current.Items["NHibernateSession"];
if (session == null) {
session = ...; // Create session, like SessionFactory.createSession()...
HttpContext.Current.Items.Add("NHibernateSession", session);
}
return session;
}
public static void CloseSession()
{
var session = HttpContext.Current.Items["NHibernateSession"];
if (session != null) {
if (session.IsOpen) {
session.close();
}
HttpContext.Current.Items.Remove("NHibernateSession");
}
}
}
By using the static methods provided by this class, one can get a session (for example, in a Controller) that is tied to the current HttpContext (the current Web request). 通过使用此类提供的静态方法,可以获得与当前HttpContext(当前Web请求)绑定的会话(例如,在Controller中)。 We need another snippet of code to call the CloseSession() method when the request is completed.
我们需要另一段代码来在请求完成时调用CloseSession()方法。
In Global.asax.cs: 在Global.asax.cs中:
protected void Application_EndRequest(object sender, EventArgs args)
{
NHibernateSessionManager.CloseSession();
}
The Application_EndRequest event is automatically called when the session is completed, so the session can be properly closed an disposed of. 会话完成后会自动调用Application_EndRequest事件,因此可以正确关闭会话并将其处理掉。 This is useful, because otherwise we would have to do this in every Controller!
这很有用,因为否则我们必须在每个Controller中执行此操作!
Use DI along with an IoC. 使用DI和IoC。 Most IoC's come with a per-request instantiation behaviour.
大多数IoC都带有每请求实例化行为。
My "solution" involves using Unity to inject session per request in controllers: 我的“解决方案”涉及使用Unity在控制器中为每个请求注入会话:
http://letsfollowtheyellowbrickroad.blogspot.com/2010/05/nhibernate-sessions-in-aspnet-mvc.html http://letsfollowtheyellowbrickroad.blogspot.com/2010/05/nhibernate-sessions-in-aspnet-mvc.html
Take a look at S#arp Architecture . 看看S#arp架构 。 It is a very nice architecture for ASP.NET MVC and NHibernate.
对于ASP.NET MVC和NHibernate来说,它是一个非常好的架构。
You can add an action filter that can manage your NHibernate session & transactions. 您可以添加一个可以管理NHibernate会话和事务的操作过滤器。 (This can be done at the action or controller level.) Here is an example of it:
(这可以在动作或控制器级别完成。)以下是一个示例:
http://weblogs.asp.net/srkirkland/archive/2009/09/03/asp-net-mvc-transaction-attribute-using-nhibernate.aspx http://weblogs.asp.net/srkirkland/archive/2009/09/03/asp-net-mvc-transaction-attribute-using-nhibernate.aspx
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.