关于Autofac如何帮助管理NHibernate ISession实例(对于ASP.NET MVC应用程序),有人有什么建议或最佳实践吗?
发布于 2010-05-09 00:44:07
我不太熟悉应该如何处理NHibernate会话。也就是说,Autofac拥有出色的实例生命周期处理(scoping和deterministic disposal)。一些相关的资源是this article和this question。由于您使用的是ASP.Net MVC,因此请确保您也要了解the MVC integration stuff。
为了说明这一点,这里有一个关于如何使用Autofac工厂委托和Owned泛型来完全控制实例生命周期的快速示例:
public class SomeController
{
private readonly Func<Owned<ISession>> _sessionFactory;
public SomeController(Func<Owned<ISession>> sessionFactory)
{
_sessionFactory = sessionFactory;
}
public void DoSomeWork()
{
using (var session = _sessionFactory())
{
var transaction = session.Value.BeginTransaction();
....
}
}
}让它工作的容器设置非常简单。请注意,我们不需要做任何事情来获取Func<>和Owned<>类型,它们是由Autofac自动提供的:
builder.Register(c => cfg.BuildSessionFactory())
.As<ISessionFactory>()
.SingleInstance();
builder.Register(c => c.Resolve<ISessionFactory>().OpenSession());更新:我在这里的推理是,根据this NHibernate tutorial,会话实例的生命周期应该是“工作单元”的生命周期。因此,我们需要一些方法来控制何时创建会话实例以及何时释放会话。
使用Autofac,我们通过请求Func<>而不是直接请求类型来获得此控件。不使用Func<>将要求在创建控制器实例之前预先创建会话实例。
接下来,Autofac中的默认设置是实例具有其容器的生命周期。因为我们知道一旦工作单元完成,我们就需要处理这个实例的能力,所以我们请求一个Owned实例。在这种情况下,释放所拥有的实例将立即释放底层会话。
发布于 2010-05-09 00:31:05
编辑:听起来像Autofac,也许其他容器可以正确地确定生命周期的范围。如果是这样的话,就去做吧。
使用IoC容器直接管理会话并不是一个好主意。会话的生命周期应该与您的工作单元(事务边界)相对应。在web应用程序的情况下,这几乎肯定是web请求的生命周期。
要实现这一点,最常见的方法是使用一个HttpModule,它在请求开始时创建会话并启动事务,然后在请求完成时提交。我会让HttpModule在HttpContext.Items集合中注册会话。
在您的IoC容器中,您可以针对ISessionLocator注册类似HttpContextSessionLocator的内容。
我应该提到,您的通用错误处理应该定位当前会话并自动回滚事务,否则您可能最终提交半个单元的工作。
https://stackoverflow.com/questions/2794626
复制相似问题