Action Filter Dependency Injection in ASP.NET MVC 3 RC2 with StructureMap
- by Ben
Hi,
I've been playing with the DI support in ASP.NET MVC RC2.
I have implemented session per request for NHibernate and need to inject ISession into my "Unit of work" action filter.
If I reference the StructureMap container directly (ObjectFactory.GetInstance) or use DependencyResolver to get my session instance, everything works fine:
ISession Session {
get { return DependencyResolver.Current.GetService<ISession>(); }
}
However if I attempt to use my StructureMap filter provider (inherits FilterAttributeFilterProvider) I have problems with committing the NHibernate transaction at the end of the request.
It is as if ISession objects are being shared between requests. I am seeing this frequently as all my images are loaded via an MVC controller so I get 20 or so NHibernate sessions created on a normal page load.
I added the following to my action filter:
ISession Session {
get { return DependencyResolver.Current.GetService<ISession>(); }
}
public ISession SessionTest { get; set; }
public override void OnResultExecuted(System.Web.Mvc.ResultExecutedContext filterContext) {
bool sessionsMatch = (this.Session == this.SessionTest);
SessionTest is injected using the StructureMap Filter provider.
I found that on a page with 20 images, "sessionsMatch" was false for 2-3 of the requests.
My StructureMap configuration for session management is as follows:
For<ISessionFactory>().Singleton().Use(new NHibernateSessionFactory().GetSessionFactory());
For<ISession>().HttpContextScoped().Use(ctx => ctx.GetInstance<ISessionFactory>().OpenSession());
In global.asax I call the following at the end of each request:
public Global() {
EndRequest += (sender, e) => {
ObjectFactory.ReleaseAndDisposeAllHttpScopedObjects();
};
}
Is this configuration thread safe? Previously I was injecting dependencies into the same filter using a custom IActionInvoker. This worked fine until MVC 3 RC2 when I started experiencing the problem above, which is why I thought I would try using a filter provider instead.
Any help would be appreciated
Ben
P.S. I'm using NHibernate 3 RC and the latest version of StructureMap