Odd question. If your concern is specifically IDisposable
, most containers will inspect the implementation, and if it contains an implementation of IDisposable
the container will invoke Dispose ()
auto-magically when it releases the instance.
So,
// pure clean business interface. no dispose member
public interface ISomeBusinessInterface { }
// an implementation that does not require any 'disposing'
// and implements *only* business interface
public class SomeBusinessImplementation :
ISomeBusinessInterface
{
}
// an implementation that contains heavy resources and
// requires 'disposing'
public class SomeDisposableBusinessImplementation :
ISomeBusinessInterface,
IDisposable
{
}
// a typical consumer. no knowledge of instance life-cycle
public class SomeConsumer
{
// injector constructor
public SomeConsumer (ISomeBusinessInterface business) { }
}
Your consumers should have no knowledge of an injected component's lifecycle, and is not in any shape way or form responsible for it. From this perspective, it makes sense that ISomeBusinessInterface
does not inherit or expose any such Dispose
method - I mean, consider if you disposed of an important singleton service! How embarassing would that be?
So who is responsible for the life-cycle of injected components? Well the container is of course! As previously mentioned, most containers will inspect component implementations for implementations of IDisposable
[also another reason to use standard CLR-defined interfaces], and will invoke Dispose
when it determines the component has reached the end of its life. So SomeDisposableBusinessImplementation
will be properly disposed of in the end. :)
Castle Windsor
Castle Windsor IoC container tracks and maintains references to all instances it creates. It uses reflection to determine if the instance is "disposable" or not, and then invokes Dispose ()
when the instance's lifecycle completes. For long-lived objects, this is when the container is disposed. For transient short-lived objects, this is when Release (object)
is explicitly invoked by consumer *.
*=which raises an important point, transient objects should be acquired via an explicit call to Resolve<T> ()
and released via an explicit call to Release (object)
. Implicitly injecting transient classes may lead to memory leaks!
StructureMap
StructureMap IoC container does not track and maintain references to transient instances. Which pretty much means object lifecycle management is a little complex +. This is great for transient short-lived objects, as there is no additional book-keeping required except the usual. However, for long-lived objects, you will have to extend the framework, reflect, and dispose of instances yourself.
+=complex imo.