Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you reconcile IDisposable and IoC?

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?

like image 498
Mr. Putty Avatar asked Jun 12 '09 16:06

Mr. Putty


People also ask

Is IDisposable called automatically?

Dispose() will not be called automatically. If there is a finalizer it will be called automatically. Implementing IDisposable provides a way for users of your class to release resources early, instead of waiting for the garbage collector.

How do IoC containers work?

The IoC container creates an object of the specified class and also injects all the dependency objects through a constructor, a property or a method at run time and disposes it at the appropriate time. This is done so that we don't have to create and manage objects manually.

What is IDisposable object?

IDisposable is an interface that contains a single method, Dispose(), for releasing unmanaged resources, like files, streams, database connections and so on.


1 Answers

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     } } 
like image 169
Mike Valenty Avatar answered Oct 04 '22 11:10

Mike Valenty