我正在尝试连接Autofac以帮助管理我的MVC 4 RC项目中的NHibernate ISession
。根据我的理解,Autofac应该按照我配置的方式在每个HTTP请求结束时调用ISession.Dispose
(见下文)。但是,似乎并非如此 - 如果我不调用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);
}
}
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: - )
答案 0 :(得分:3)
提交事务将刷新会话。交易是基础知识的一部分。
- 或 -
启用NHibernate日志记录,您将看到AutoFac是否处理会话以及NHibernate是否自动刷新。
您已将AutoFac配置为应在lifetimescope的末尾处置会话。你在哪里配置lifetimescope应该匹配http请求?
<强>更新强>
我自己测试了它,如果会话被处理,会话没有被刷新。这是有道理的,因为您通常使用的事务将在会话处理之前提交。否则,会话将在事务之外刷新。
因此要么将flushmode设置为'Always',要么使用事务。就像我在原始答案中所说,交易是基础知识的一部分。
答案 1 :(得分:1)
我对AutoFac一无所知,因为我最喜欢的DI框架是Spring.NET及其XML :)。 但是对于我来说,对某些事物的变化并不持久的问题是非常熟悉的。在我得到的所有情况下,它们都与刷新模式和事务有关。我按照以下程序处理这些:
首先检查是交易。它到位了吗?强烈建议至少在事务中执行所有更新/删除操作。我们假设交易确实开始了。
我们进入冲洗模式。会话的刷新模式是什么?如果是Commit,则应保持更改。如果是自动,则还必须保留更改。所以我认为它是Never,它要求你使用Session.Flush()手动刷新它。