IOC Containers, HttpContext Managed Lifecycle and Disposable Objects

I like to use an IOC container to resolve web services in my controllers. I also like the IOC container to manage the lifetime of those services, so that my controllers are not fussed about having to dispose of things themselves, like the simple controller below:

public class HomeController : Controller{
  private IMyService service = null;

  public HomeController(IMyService service){
    this.service = service;
  }

  public ActionResult Index(int? id){
    return View(service.Echo("some random string"));
  }       
}

This sort of scenario is also very relevant to single tier applications where you might have an ORM context holding unmaterialised collections that are then enumerated in the view. If the context is disposed before the collection is enumerated, an exception will be thrown.

So, that leads us down the path of using object LifeTime managers. Which is fine becuase IOC containers such as StructureMap and Unity support managed lifetimes. StructureMap in fact with a comes with a HttpContextLifeTime manager out of the box. This sounds very promising (it's got a method called DisposeAndClearAll which I assume would dispose of any objects for me), so let's wire it up:

ObjectFactory.Configure(c =>{
 c.For<IMyService>().LifecycleIs(new HttpContextLifecycle()).Use<MyService>();
});

Great, that was easy. The only problem however is that while I get a new object each request, Dispose() is never called on my objects so I'll quickly exhaust the number of available channels under load.

Fortunately this is not a difficult problem to solve. You could either create a HttpModule to hook into the EndRequest event and call ObjectFactory.ReleaseAndDisposeAllHttpScopedObjects(), or implement the following in Global.asax:

void Application_EndRequest(object sender, EventArgs e){
  ObjectFactory.ReleaseAndDisposeAllHttpScopedObjects();
}

Unity does not come with a HttpContext lifetime manager out of box, but writing one isn't too difficult.

Updated 25 Jan 2011

I have subsequently designed a common ContextLifetimeManager that can be used for both HttpContext and WCF scenarios. It is a much better design than what I had here previously.

I have correspondingly modifed the code in this post to reflect the new design. In Application_Start, configure your container. Implement the Application_EndRequest method, and call the neccesary ReleaseAndDisposeAll method. Note the use of the ServiceLocator container wrapper - this will maintain the static reference to the one UnityContainer.

protected void Application_Start(){
  UnityContainer container = new UnityContainer();

  container.RegisterInstance<IContextItemsProvider>(new HttpContextItemsProvider());
  container.RegisterType<IMyService, MyService>(container.Resolve<ContextLifetimeManager>());


  ...
  ServiceLocator.SetLocatorProvider(() => new UnityServiceLocator(container));
}

void Application_EndRequest(object sender, EventArgs e){
  ContextLifetimeManager.ReleaseAndDisposeAll(ServiceLocator.Current.GetInstance<IContextItemsProvider>());
}

Conclusion

I've covered the correct way (IMHO) of using StructureMap and Unity IOC containers with an object lifetime of the HttpContext. If you are planning on using Unity as your IOC container in an ASP.net MVC application, you might be interested in bootstrapping it and registering it as the Dependency Resolver.

kick it on DotNetKicks.com

About these ads
This entry was posted in ASP.Net MVC, StructureMap, Unity. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s