nhibernatestructuremaprhino-security

Instruct StructureMap to create a NEW Session (only when disposed)


I am using StructureMap with Nhibernate and I would like to instruct the tool to build a new session everytime is needed, and only if is disposed.
I'll try to explain with some code (this is a console application).

I build my session factory this way (ConnDb is my connection string):

For<ISessionFactory>()
 .Singleton()
 .Use(() => new NHSessionFactory(ConnDb, true).SessionFactory);

and this is the code I use to build a session:

For<ISession>()
  .Singleton()
  .Use(x => x.GetInstance<ISessionFactory>().OpenSession());

Everything works as expected when I don't dispose the session but I would like to be able to do something like this:

    using (session)
    {
        using (var tx = session.BeginTransaction())
        {
            // DO SOMETHING
            tx.Commit();
        }
    }

    using (session)
    {
        using (var tx = session.BeginTransaction())
        {
            // DO SOMETHING
            tx.Commit();
        }
    }

I've tried to change the code for the session, like this:

For<ISession>()
  .AlwaysUnique()
  .Use(x => x.GetInstance<ISessionFactory>().OpenSession());

but I've noticed that now a new session is created even if there's one active. In my situation I am referencing another component (Rhino.Security) which resolve the ISession with a service locator.


Solution

  • The Session should be disposed by the creator of the Session, not by any client. You should consider revising your architecture to have the Session created and disposed within the same scope.

    The Session life span should be limited to fit the component that uses it. By having one global session (as with your singleton attempt) the session will hold references to all entities that you have accessed any time during your application's lifespan - effectively eating up your memory. Also if your session throws an exception it will be in an undetermined state and will bring your entire application down.

    Read Ayende's article in MSDN magazine on how to use NHibernate with Desktop Applications. The advice he gives is with high likelyhood also applicable to your scenario.

    When it comes to handling Sessions with StructureMap Jeremy Miller has a blog post on how he does it - using nested containers to control the lifespan. Jeremy's example is probably overkill if the application is simple. You should probably focus on injecting one session per component/command in your application.