使用IoC时如何管理对象处理?

时间:2010-04-09 19:10:08

标签: dependency-injection inversion-of-control ioc-container ninject

我的情况是Ninject 2。

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

但有时我需要保持上下文更长时间或在函数调用之间。 所以我想通过IoC范围来控制这种行为。

// 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>()) 
{
}

示例范围

Container.Bind<IContext>().To<EFContext>().InSingletonScope();
// OR
Container.Bind<IContext>().To<EFContext>().InRequestScope();

3 个答案:

答案 0 :(得分:3)

据我所知(我在一个月前做了一项研究)Ninject根本不支持生命周期管理。 Castle Windsor和AutoFac(以及某种程度上的StructureMap,但仅在使用嵌套容器时)将负责处理他们在适当时间创建的一次性组件。

答案 1 :(得分:1)

如果您可以控制IContext的接口,请将IDisposable添加到其继承的接口列表中。如果没有,请将IContext转发给IDisposable ......

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

using ((IDisposable)context)
{
}

如果您控制IContext,您还可以选择更改IContext的界面来执行此操作...

public interface IContext
{
   // ...

   IDisposable GetUsageHandle();
}

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

using (context.GetUsageHandle())
{
}

答案 2 :(得分:1)

除了Transient,OnePerThread和Singleton的标准范围之外,您还可以使用ActivationBlock来控制整组对象的生命周期。当块被释放时,块所检索的所有对象都超出范围 - 因此当激活块请求它们的实例时,单个和其他对象将被处理掉。

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();