c# - practices - unity idisposable




How do you reconcile IDisposable and IoC? (5)

I'm finally wrapping my head around IoC and DI in C#, and am struggling with some of the edges. I'm using the Unity container, but I think this question applies more broadly.

Using an IoC container to dispense instances that implement IDisposable freaks me out! How are you supposed to know if you should Dispose()? The instance might have been created just for you (and therefor you should Dispose() it), or it could be an instance whose lifetime is managed elsewhere (and therefor you'd better not). Nothing in the code tells you, and in fact this could change based on configuration!!! This seems deadly to me.

Can any IoC experts out there describe good ways to handle this ambiguity?


AutoFac handles this by allowing the creation of a nested container. When the container is finished with, it automatically disposes of all IDisposable objects within it. More here.

.. As you resolve services, Autofac tracks disposable (IDisposable) components that are resolved. At the end of the unit of work, you dispose of the associated lifetime scope and Autofac will automatically clean up/dispose of the resolved services.


I think in general the best approach is to simply not Dispose of something which has been injected; you have to assume that the injector is doing the allocation and deallocation.


Putting a facade in front of the container can resolve this as well. Plus you can extend it to keep track of a more rich life cycle like service shutdowns and startups or ServiceHost state transitions.

My container tends to live in an IExtension that implements the IServiceLocator interface. It is a facade for unity, and allows for easy access in WCf services. Plus I have access to the service events from the ServiceHostBase.

The code you end up with will attempt to see if any singleton registered or any type created implements any of the interfaces that the facade keeps track of.

Still does not allow for the disposing in a timely manner as you are tied to these events but it helps a bit.

If you want to dispose in a timely manner (aka, now v.s. upon service shutdown). You need to know that the item you get is disposable, it is part of the business logic to dispose of it, so IDisposable should be part of the interface of the object. And there probably should be verification of expectations untitests related to the dispose method getting called.


This depends on the DI framework. Some frameworks allow you to specify whether you want a shared instance (always using the same reference) for every dependency injected. In this case, you most likely do not want to dispose.

If you can specify that you want a unique instance injected, then you will want to dispose (since it was being constructed for you specifically). I'm not as familiar with Unity, though - you'd have to check the docs as to how to make this work there. It's part of the attribute with MEF and some others I've tried, though.


You definitely do not want to call Dispose() on an object that was injected into your class. You can't make the assumption that you are the only consumer. Your best bet is to wrap your unmanaged object in some managed interface:

public class ManagedFileReader : IManagedFileReader
{
    public string Read(string path)
    {
        using (StreamReader reader = File.OpenRead(path))
        {
            return reader.ReadToEnd();
        }
    }
}

That is just an example, I would use File.ReadAllText(path) if I were trying to read a text file into a string.

Another approach is to inject a factory and manage the object yourself:

public void DoSomething()
{
    using (var resourceThatShouldBeDisposed = injectedFactory.CreateResource())
    {
        // do something
    }
}






idisposable