有没有关于如何使用Autofac来管理NHibernate ISession实例(在ASP.NET MVC应用程序中)的提示或最佳实践?
有没有关于如何使用Autofac来管理NHibernate ISession实例(在ASP.NET MVC应用程序中)的提示或最佳实践?
我对NHibernate会话的处理方式并不是非常熟悉。 话虽如此,Autofac在实例生命周期管理(范围和确定性处理)方面表现出色。一些相关资源包括这篇文章和这个问题。由于您在ASP.Net MVC中,请确保您还研究一下MVC集成功能。
为了说明这一点,这里有一个快速示例,展示如何使用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());
更新: 我的推理是,根据此NHibernate教程的说法,会话实例的生命周期应该与“工作单元”相同。因此,我们需要一些方法来控制会话实例的创建和处理时间。
通过使用Autofac,我们可以通过请求Func<>
而不是直接请求类型来获得这种控制。如果不使用Func<>
,则需要在控制器实例创建之前预先创建会话实例。
接下来,Autofac的默认设置是实例的生命周期与其容器相同。由于我们知道需要在工作单元完成后立即处理此实例,因此我们请求一个Owned
实例。在这种情况下,处理拥有的实例将立即处理底层会话。
编辑:听起来像是Autofac以及其他容器可以正确地控制生命周期。如果是这样的话,请继续使用。
直接使用IoC容器管理会话并不是一个好主意。您的会话生命周期应该对应于工作单元(事务边界)。在Web应用程序的情况下,几乎肯定应该是Web请求的生命周期。
最常见的方法是使用HttpModule,在请求开始时创建会话并启动事务,然后在请求完成时提交。我建议HttpModule将会话注册到HttpContext.Items集合中。
在您的IoC容器中,可以注册类似于HttpContextSessionLocator的ISessionLocator。
我应该提到,您的通用错误处理应该定位当前会话并自动回滚事务,否则您可能会提交一半的工作单元。