为什么使用Autofac时我的ISession不会自动刷新?

时间:2012-07-25 09:11:03

标签: nhibernate asp.net-mvc-4 autofac

概述

我正在尝试连接Autofac以帮助管理我的MVC 4 RC项目中的NHibernate ISession。根据我的理解,Autofac应该按照我配置的方式在每个HTTP请求结束时调用ISession.Dispose(见下文)。但是,似乎并非如此 - 如果我不调用ISession.Flush(),数据不会保留在数据库中。

配置

Autofac

container.Register(c => DbConfig.Generate(connectionString).BuildSessionFactory())
    .As<ISessionFactory>()
    .SingleInstance();

container.Register(c => c.Resolve<ISessionFactory>().OpenSession())
    .As<ISession>()
    .InstancePerLifetimeScope();

container.RegisterGeneric(typeof(Repository<>))
    .As(typeof(IRepository<>))
    .InstancePerLifetimeScope();

存储库

public class Repository<T> : IRepository<T> where T : class
{
    protected readonly ISession Session;

    public Repository(ISession session)
    {
        Session = session;
    }

    public void Add(T entity)
    {
        Session.Save(entity);
    }
}

数据库种子(Application_Start)

public class DatabaseSeed
{
    public static void Seed(IContainer container)
    {
        var session = container.Resolve<ISession>();
        var userRepo = container.Resolve<IRepository<User>>();
        userRepo.Add(new User { Id = 5, Name = "Test User" });

        //session.Flush(); <-- if not called, user will not be persisted!
    }
}

结束语

我知道我应该在交易中包装它。但是,在进入更复杂的场景之前,我想先了解基础知识,并且很困惑为什么上述内容不能像我预期的那样工作......

(作为旁注,我尝试运行Whitebox,Autofac'探查器',但它失败了我有一些例外(在Autofac组@Google上发布),所以我不完全确定它是否是Autfac那取笑我或NHibernate: - )

2 个答案:

答案 0 :(得分:3)

提交事务将刷新会话。交易是基础知识的一部分。

- 或 -

启用NHibernate日志记录,您将看到AutoFac是否处理会话以及NHibernate是否自动刷新。

您已将AutoFac配置为应在lifetimescope的末尾处置会话。你在哪里配置lifetimescope应该匹配http请求?


<强>更新

我自己测试了它,如果会话被处理,会话没有被刷新。这是有道理的,因为您通常使用的事务将在会话处理之前提交。否则,会话将在事务之外刷新。

因此要么将flushmode设置为'Always',要么使用事务。就像我在原始答案中所说,交易基础知识的一部分。

答案 1 :(得分:1)

我对AutoFac一无所知,因为我最喜欢的DI框架是Spring.NET及其XML :)。 但是对于我来说,对某些事物的变化并不持久的问题是非常熟悉的。在我得到的所有情况下,它们都与刷新模式和事务有关。我按照以下程序处理这些:

首先检查是交易。它到位了吗?强烈建议至少在事务中执行所有更新/删除操作。我们假设交易确实开始了。

我们进入冲洗模式。会话的刷新模式是什么?如果是Commit,则应保持更改。如果是自动,则还必须保留更改。所以我认为它是Never,它要求你使用Session.Flush()手动刷新它。