I hope to make this a weekly post reflecting on the topics of the week and writing about what came up that was new or that gave me a better understanding of some technology or related topic. We’ll see how long this lasts…
So, I am currently working on an implementation of Entity Framework 4 using WCF and WPF with Prism and, until this week, Unity. I am relatively new to the unit testing bandwagon, and in particular, to dependency injection and inversion of control. I must say, however, that I have quickly become a fan as I have personally witnessed higher quality code with better and more flexible designs being relied upon.
I came across a realization this week how resolving classes with an IoC container that have implemented IDisposable, or worse yet, have dependencies being injected that implement IDisposable somewhere down their dependency chain, can cause headaches. At some point, these disposable instances need to get disposed, but how? They are dependencies to a class instance, but they are not owned by the class instance. Therefore, implementing IDisposable at the top level and disposing of the dependencies that way is out. One could end up disposing a dependency that is shared among other instances. Even if one could implement disposable at the top level, one would still have to keep a reference around at the point of resolution (Resolve call on the container) so that dispose could later be called on it. That can be difficult and/or awkward in some circumstances.
Of course, my first thought, as it often is, is there is no way that I am the first to have come across this problem. Time to Bing it! I was a bit surprised how little people have talked about this particular issue, but there were a few articles out there that mentioned it. I would credit them here, but I don’t recall them at the moment. Most pointed to the fact that Unity is deficient in this area and pointed to Castle Windsor and Autofac as two other IoC containers that make this issue easier to deal with. Both Windsor and Autofac allow one to create scoped sub-containers that track all of the instances that they new-up and later dispose of those instances when the scope is left. For Autofac the code looks like this:
using (var containerScope = SrsIoCContainer.Current.BeginLifetimeScope())
{
var calculator = containerScope.Resolve<ITimeCalculatorService>();
return calculator.GetAccumulatedByEmployee(employee, asOfDate);
}
I looked all over Unity for something similar or for a work-around that might accomplish the same thing, but couldn’t find one. The above, from Autofac, solves the issue, and since the IoC container is a pretty small and isolated piece of the software, I have decided to replace Unity with Autofac (still on-going because of Prism’s dependence on Unity for bootstrapping; not as isolated as I had originally thought).
Unfortunately, scoped containers still don’t help when Service Location is brought into the mix. The service locator is setup to use the IoC container as its provider, which works great, but what happens when a service location, which cannot be scoped, new-ups a disposable instance indirectly? I have not come to a full resolution on that yet, other than to avoid service location whenever possible, and, when it is necessary, ensure that the class chain it is resolving will not result in a disposable instance being created by the container.