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

问题描述:

概述

我想连线Autofac来帮助管理我的MVC 4 RC项目中的NHibernate的ISession。根据我的理解,Autofac应该按照我配置它的方式在每个HTTP请求的末尾调用ISession.Dispose(见下文)。但是,似乎并不是这种情况 - 如果我没有拨打ISession.Flush(),数据不会保留在数据库中。为什么我的ISession在使用Autofac时不会自动刷新?

配置

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! 
    } 
} 

闭幕词

我知道我应该在交易中包装这个。然而,我想在继续研究更复杂的场景之前先掌握一些基础知识,并且为什么上述方法不能按照我期望的方式工作,我感到困惑......

(作为附注,我尝试运行Autofac'profiler'这个Whitebox,但是它对我有些不正常(在Autofac group @ Google上发布),所以我不完全确定它是Autfac,它取笑我还是NHibernate :-)

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

- 或 -

打开NHibernate的日志和,你会看到,如果AutoFac部署的会议,如果NHibernate的刷新本身。

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


UPDATE

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

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

+0

正如我所说,我知道将整个事情包装在一个事务中并提交它可以解决问题,但我试图理解为什么更简单的解决方案似乎不够用。 AFAIK InstancePerLifetimeScope在Web应用程序中使用时默认为每个HTTP请求的实例。 – Dav 2012-07-25 09:30:34

+0

这就是为什么你可以打开NHibernate日志记录来查看它的功能。 – Jeroen 2012-07-25 09:31:14

+0

你的确说得对,'Dispose'本身并不会导致所有挂起的命令执行。我在想这可能是一些Autofac相关的,对象生存期的问题,但是由于测试的结果,我将db-init代码移到了控制器中,并且经历了相同的行为。不知道我在哪里得到了“Dispose”应该自动刷新的想法,除非另有说明......从其他人对互联网上的评论中,交易确实被期望用作任何操作的标准部分。感谢您花时间回复并测试! – Dav 2012-07-25 10:42:02

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

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

我们来到冲水模式。会话的冲洗模式是什么?如果是Commit,则应该保持更改。如果它是Auto,则更改也必须持续。所以我认为这是从不,这需要你使用Session.Flush()手动刷新它。

+0

麻烦的是我根本没有使用事务,只是在做'ISession。保存(某物)'并且希望当'ISession'被丢弃时这最终会被刷新/保持。现在我有交易(仍然使用'FlushMode.Auto'),问题不复存在,我可以继续讨论更多有趣的事情:-) – Dav 2012-07-25 15:00:06