views:

145

answers:

3

My case it is Ninject 2.

// normal explicit dispose
using (var dc = new EFContext) 
{
}

But sometimes I need to keep the context longer or between function calls. So I want to control this behavior through IoC scope.

// if i use this way. how do i make sure object is disposed.
var dc = ninject.Get<IContext>() 

// i cannot use this since the scope can change to singleton. right ??
using (var dc = ninject.Get<IContext>()) 
{
}

Sample scopes

Container.Bind<IContext>().To<EFContext>().InSingletonScope();
// OR
Container.Bind<IContext>().To<EFContext>().InRequestScope();
+1  A: 

If you have control over the interface of IContext, add IDisposable to the list of interfaces from which it inherits. If not, downcast the IContext you get to an IDisposable...

var context = ninject.Get<IContext>();

using ((IDisposable)context)
{
}

You also have the option of altering the interface of IContext to do this by composition, if you control IContext...

public interface IContext
{
   // ...

   IDisposable GetUsageHandle();
}

var context = ninject.Get<IContext>();

using (context.GetUsageHandle())
{
}
thanks. what if i change my scope to singleton in the above case? It dispose. right, Next time i call that function, you get exception.
Aval
@Aval: Right, which is why you would want to use the second implementation, where the context produces something that is _not_ a Singleton that is disposable. Better, still, you can start out by having the second implementation just return the disposable object and then change to having a singleton with disposable flyweights without impacting the client.
thanks, it's really helped me.
Aval
+2  A: 

From what I know (I did a research about a month ago) Ninject does not support lifecycle management at all. Castle Windsor and AutoFac (and to some extent StructureMap, but only when using nested containers) will take care of disposing disposable components they create at appropriate time.

Krzysztof Koźmic
+2  A: 

In addition to the standard scopes of Transient, OnePerThread, and Singleton, you can use an ActivationBlock in order to control the lifetime of a whole set of objects. When the block is disposed, all object retrieved by the block go out of scope - so singletons and others are disposed of when their instances are requested by the activation block.

var kernel = new StandardKernel();
kernel.Bind<NotifiesWhenDisposed>().ToSelf();

NotifiesWhenDisposed instance = null;
using(var block = new ActivationBlock(kernel))
{
    instance = block.Get<NotifiesWhenDisposed>();
    instance.IsDisposed.ShouldBeFalse();
}

instance.IsDisposed.ShouldBeTrue();
Ian Davis