where to release and dispose?

Jul 14, 2010 at 5:35 PM

We are new to MVCTurbine, and are looking to convert existing StructureMap/NHibernate installations.  In particular, we have used the Application_EndRequest() method to tell StructureMap to dispose things properly, as follows:

protected void Application_EndRequest()


How can we achieve the same thing now that our global.asax inherits from TurbineApplication instead?



Jul 14, 2010 at 9:44 PM
Further information... it seems the Application_EndRequest() method is still called at the right time, so it isn't a matter of "moving this code to some other event" as much as it is a matter of getting the right instance of the ObjectFactory. It seems confusing, but can be described as follows: Before Turbine, when this method was called, we could clearly see that the ObjectFactory contained a bunch of registrations. Now that we have Turbine, when this method is called, it doesn't fail, but... it doesn't "have" the registrations. Making us think that it wont be disposing of anything :) In a few other places where we have had calls to ObjectFactory, we have done the following: var locator = MvcTurbine.ComponentModel.ServiceLocatorManager.Current as MvcTurbine.StructureMap.StructureMapServiceLocator; var logProvider = (ILogProvider)locator.Container.GetInstance(typeof(ILogProvider)); So, we are getting the Turbine "instance" of the underlying container, and using it to get an instance of the service (ILogProvider in this example). That seems to work just fine. BUT, that method doesnt work for the ReleaseAndDisposeAllHttpScopedObjects() method. It doesn't exist on the locator.Container reference. So we can only go with the ObjectFactory static, which apparently just isn't meant to be used once you're in Turbine. I hope this clarifies a bit. Also, I know not to throw around ObjectFactory.GetInstance calls all over the place :) We are talking about a couple of instances deep in the bowels of the infrastructure code. Thanks! Travis
Jul 14, 2010 at 10:13 PM
Gotcha! Yes ObjectFactory uses it's on internal container, so when Turbine creates a new container they're not the same. However, making them the same is pretty easy :) See this code sample - http://gist.github.com/476047 Does his aid your problem? Also, you might want to consider the way you're resolving ILogProvider. Why not use ServiceLocatorManager.Current.Resolve<ILogProvider>() or just inject ILogProvider into the types that need it and spin those from the controller? Just a couple of thoughts.
Jul 31, 2010 at 3:05 PM

Javier - thanks, but we have discovered a show-stopping problem with this approach.


Please see this link: http://stackoverflow.com/questions/3344652/adding-removing-a-file-in-vs2010-causes-webdev-webserver20-exe-has-stopped-worki


As it turns out, the problem is caused by Turbine, or by the specific Turbine/StructureMap interaction you suggested in our most recent exchange.  Specifically, this line causes the problem:


ServiceLocatorManager.SetLocatorProvider(() => new StructureMapServiceLocator(container));


It does not throw an error.  As a matter of fact, it does seem to "work."  But for some reason, bizarre to me, it causes the behavior mentioned in the StackOverflow question.  You can easily re-create the problem by creating a new MVC2 project in 2010, adding your Turbine and StructureMap references, inheriting the global.asax and putting that into the ctor as suggested.


Any help you can provide would be greatly appreciated.  I really would not like to go back to the non-Turbine world.  Certainly not before MVC3 :)



Jul 31, 2010 at 4:37 PM
Hi Travis, Yes the team has discussed this issue and we have a fix to apply in v2.2. The reason is a stackoverflow exception when disposing the ServiceLocator. Since we register the SeviceLocator with itself and we call dispose, essentially it calls dispose on all the types that it has registered, including it self. So this causes a recursive loop of calls to ServiceLocator.Dispose which causes the WebDevServer to crash. You can fix it by adding this to your StructureMapApplication type this: protected override void ShutdownContext() { CurrentContext = null; ServiceLocator = null; } Essentially you're preventing the disposition of the ServiceLocator from happing since this piece gets called at App_Shutdown. The fix for v2.2 will not be this, instead it will be addressed at the ServiceLocator registration. I've updated the code sample here http://github.com/jglozano/mvcturbine/blob/master/src/Samples/SMExtensions/Mvc/StructureMapTurbineApplication.cs -- fell free to check it out. Any questions, please don't hesitate to contact me. Hope this help!
Jul 31, 2010 at 7:29 PM

Awesome, thanks!