IOC Containers and IDisposable

Topics: General discussion
Oct 21, 2009 at 10:01 PM
Edited Oct 22, 2009 at 1:30 AM

All the application blocks, except Unity, are represented in these codeplex forums.  Is this "general discussion" the right place to post questions relating to unity?

I have not yet used IOC containers, but I'm studying TDD and am evaluating IOC container implementations (Castle Windsor, Autofac, Unity, StructureMap, etc).

In general, I'm finding there is a significant problem regarding the handling of IDisposable objects from an IOC container.  The topic has been discussed here:

http://stackoverflow.com/questions/987761/how-do-you-reconcile-idisposable-and-ioc

...but was not actually answered.

The problem is that there is no way for a client class to know if an injected dependency is IDisposable (without using reflection, which is not acceptable).  Instead, the IOC containers themselves implement IDisposable and use reflection to determine which created / provided objects are IDisposable.  Thats good.  However, the Unity container doesn't keep track of most objects it creates - which makes calling Dispose() on the Unity container near useless.  Other containers, such as Windsor and Autofac, keep track of *all* IDisposable objects they make / contain.  But there is still a problem.  Calling Dispose() on those containers effectively ends the lifecycle of the container, which leaves the client orphaned from further IOC access.  To compensate, the application code will often post-pone calling Dispose() on the container as long as possible - the opposite of what normally would be designed and coded. 

If there is something I'm completely misunderstanding, please explain.  Otherwise, I'm hoping someone can discuss strategies that minimize this problem.  Until that time, some solutions I'm considering are:

1) Don't use TDD / IOC containers.  Instead use traditional testing techniques (emphasis on component levelization and interface based testing).

2) If using TDD / IOC containers, then adhere to both:
  a) Don't use Unity (use AutoFac or Windsor instead, because they track every single IDisposable object they make).
  b) Never Resolve() on the parent container directly.  Instead, every recipient of the parent immediately makes a child container(s) and calls resolve on that instead.  When finished, the client always calls Dispose() on the child container.  So if there were any IDisposables created, they are freed quickly.

My above solution #2 ASSUMES that the child container tracks objects provided by Resolve(), even though the Register() may have been made on the parent container. 

I'm looking forward to discussion on this.

Oct 22, 2009 at 1:32 AM

Unity has its own discussion forum.  Please post this question here - http://www.codeplex.com/unity/Thread/List.aspx

 

Sarah Urmeneta
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com