1

概述

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

配置

自动法

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 :-)

4

2 回答 2

3

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

- 或者 -

打开 NHibernate 日志记录,您将看到 AutoFac 是否处理会话以及 NHibernate 是否自行刷新。

您将 AutoFac 配置为应在生命周期结束时释放会话。你在哪里配置生命周期应该匹配一个 http 请求?


更新

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

因此,要么将刷新模式设置为“始终”,要么使用事务。就像我在原始答案中所说的那样,交易基础的一部分。

于 2012-07-25T09:23:54.610 回答
1

我对 AutoFac 一无所知,因为我最喜欢的 DI 框架是 Spring.NET 及其 XML :)。但是对对象进行更改的问题并没有持续存在,这对我来说非常熟悉。在我得到的所有情况下,它们都与刷新模式和事务有关。我通过以下程序处理这些:

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

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

于 2012-07-25T13:30:39.447 回答