17

关于 Autofac 如何帮助管理 NHibernate ISession 实例(对于 ASP.NET MVC 应用程序),是否有人有任何提示或最佳实践?

4

2 回答 2

21

我不太熟悉应该如何处理 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<>直接请求 a 而不是类型来获得这种控制。不使用Func<>将要求在创建控制器实例之前预先创建会话实例。

接下来,Autofac 中的默认设置是实例具有其容器的生命周期。因为我们知道一旦工作单元完成我们需要处理这个实例的能力,我们请求一个Owned实例。在这种情况下,处置拥有的实例将立即处置基础会话。

于 2010-05-08T16:44:07.240 回答
0

编辑:听起来像 Autofac 和可能其他容器可以正确地确定生命周期。如果是这样,那就去吧。

使用 IoC 容器直接管理会话不是一个好主意。会话的生命周期应与您的工作单元(事务边界)相对应。对于 Web 应用程序,这几乎可以肯定是 Web 请求的生命周期。

实现这一点的最常见方法是使用 HttpModule 来创建会话并在请求开始时启动事务,然后在请求完成时提交。我会让 HttpModule 在 HttpContext.Items 集合中注册会话。

在您的 IoC 容器中,您可以针对 ISessionLocator 注册类似 HttpContextSessionLocator 的内容。

我应该提到,您的通用错误处理应该定位当前会话并自动回滚事务,否则您最终可能会提交半个工作单元。

于 2010-05-08T16:31:04.693 回答