使用Autofac管理NHibernate ISession

时间:2010-05-08 15:32:52

标签: nhibernate autofac

有没有人有关于Autofac如何帮助管理NHibernate ISession实例的任何提示或最佳实践(在ASP.NET MVC应用程序的情况下)?

2 个答案:

答案 0 :(得分:19)

我不太熟悉如何处理NHibernate会话。也就是说,Autofac具有出色的实例生命周期处理能力(scopingdeterministic disposal)。一些相关资源是this articlethis 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实例。在这种情况下,处置所拥有的实例将立即处置基础会话。

答案 1 :(得分:0)

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

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

实现这一目标的最常见方法是使用HttpModule,它既可以创建会话,也可以在请求开始时启动事务,然后在请求完成时提交。我希望HttpModule在HttpContext.Items集合中注册会话。

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

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