Should session transactions in ASP.NET MVC be per request or per action, and if they should be per action (which I think they should), how do you scope the sessions to be per action when they are controlled via IoC (I'm using StructureMap as my Dependency Resolver)? Most implementations of a scope lifecycle in IoC containers are per HttpContext and/or per thread at their most granular setup I think, but mvc requests can have multiple actions via child actions. I thought about requesting the session factory in my action attribute controlling my transactions and create a session from that, but then how do you ensure that data repositories use the same session as the action they are being accessed by?
2 Answers
I think the most straightforward way is to use factory method and per request scope. Then the session is created when actually needed and stays alive to the end of the request.
Using only one session per request makes things easier when you have lazy load properties for example.
I don't know about StructureMap, but with Castle Windsor I only need one line
container.Register<ISession>(c => c.Resolve<ISessionFactory>().OpenSession(), LifeStyle.PerRequest);
and sessions work like a charm.
Comments
I ended up using a Attribute added to MVC at the global level that would give me a new session per Action context. I derived information from http://ayende.com/blog/4809/refactoring-toward-frictionless-odorless-code-what-about-transactions and http://slynetblog.blogspot.com/2011/04/lightweight-nhibernate-and-aspnet-mvc.html.