为什么我的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设置为“始终”或使用事务。就像我在我的原始答案中所说的,交易是的一部分基础知识。
我对AutoFac一无所知,因为我最喜欢的DI框架是Spring.NET及其XMLs :)。 但不知何故,改变对象的问题并没有持续存在,这对我来说是非常熟悉的。在我得到的所有情况下,它们都与刷新模式和事务有关。我按照以下程序处理这些问题:
首先检查是交易。它到位了吗?强烈建议您至少在交易中进行所有更新/删除操作。我们假设事务已经开始。
我们来到冲水模式。会话的冲洗模式是什么?如果是Commit,则应该保持更改。如果它是Auto,则更改也必须持续。所以我认为这是从不,这需要你使用Session.Flush()手动刷新它。
麻烦的是我根本没有使用事务,只是在做'ISession。保存(某物)'并且希望当'ISession'被丢弃时这最终会被刷新/保持。现在我有交易(仍然使用'FlushMode.Auto'),问题不复存在,我可以继续讨论更多有趣的事情:-) – Dav 2012-07-25 15:00:06
正如我所说,我知道将整个事情包装在一个事务中并提交它可以解决问题,但我试图理解为什么更简单的解决方案似乎不够用。 AFAIK InstancePerLifetimeScope在Web应用程序中使用时默认为每个HTTP请求的实例。 – Dav 2012-07-25 09:30:34
这就是为什么你可以打开NHibernate日志记录来查看它的功能。 – Jeroen 2012-07-25 09:31:14
你的确说得对,'Dispose'本身并不会导致所有挂起的命令执行。我在想这可能是一些Autofac相关的,对象生存期的问题,但是由于测试的结果,我将db-init代码移到了控制器中,并且经历了相同的行为。不知道我在哪里得到了“Dispose”应该自动刷新的想法,除非另有说明......从其他人对互联网上的评论中,交易确实被期望用作任何操作的标准部分。感谢您花时间回复并测试! – Dav 2012-07-25 10:42:02