Reputation: 1102
I'm trying to wire up Autofac to help manage NHibernate's ISession
in my MVC 4 RC project. From what I understood, Autofac should call ISession.Dispose
at the end of each HTTP request the way I configured it (see below). However, it doesn't seem to be the case - if I do not call ISession.Flush()
, data is not persisted in the database.
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!
}
}
I do know that I should be wrapping this in a transaction. However, I'd like to get the basics to work before moving on to more complex scenarios, and am puzzled as to why would the above not work the way I expected it to...
(As a side note, I tried running Whitebox, the Autofac 'profiler', but it fails on me with some exception (posted on Autofac group @ Google), so I'm not entirely sure if it's Autfac that's making fun of me or NHibernate :-)
Upvotes: 1
Views: 954
Reputation: 525
I don't know anything about AutoFac, as my favourite DI framework is Spring.NET and its XMLs :). But the problem with changes to object somehow did not persist is very familiar to me. In all cases that I got, they are related to the flush mode and transaction. I handle these with following procedure:
First to check is the transaction. Did it in place? It is strongly suggested that at least you do all updates/deletes in transaction. Let's assume that a transaction did started.
We come to the flush mode. What is the flush mode of the session? If it was Commit, changes should be persisted. If it was Auto, changes must also be persisted. So I think it was Never, which requires you to flush it manually using Session.Flush().
Upvotes: 1
Reputation: 989
Committing the transaction will flush the session. Transactions are part of the basics.
- Or -
Turn on NHibernate logging and you'll see if AutoFac disposes the session and if NHibernate flushes itself.
You configured AutoFac that the session should be disposed at the end of the lifetimescope. Where did you configure that the lifetimescope should match a http request?
UPDATE
I just tested it myself and the session isn't being flushed if the session is disposed. Which makes sense, because the transaction you normally use will be committed before the session is disposed. Otherwise the session is flushed outside of a transaction.
So either set the flushmode to 'Always' or use transactions. Like I said in my original answer, transactions are part of the basics.
Upvotes: 4