2012-09-13 27 views
2

我目前正在测试一些项目的IoC框架,我很乐意能够使用Ninject 3.如何解除Ninject 3中的具体自绑定单例绑定?

我遇到了一个问题,在配置绑定到具体类型的单例之后,我似乎无法在以后有效地取消绑定服务类型。即StandardKernel.TryGet<T>()在调用StandardKernel.Unbind<T>()后返回一个非空值。请参阅下面的代码段,了解我的确切用法。

这是在Ninject 3中的错误,或者是有什么我失踪?

作为一种变通方法,我可以简单地重新绑定具体类型为恒定空值。但我更愿意理解,如果在我退回到那个位置之前我没有做些什么。

顺便说一句,如果我指定绑定到单范围内的具体类型的接口,但不适合在单身范围内绑定具体类型的自我预期解除绑定的作品。如果这不是一个错误(和额外的业力),你能解释为什么行为有差异吗?

public class MyServiceType : IDisposable 
{ 
    public bool IsDisposed { get; private set; } 
    public void Dispose() 
    { 
     IsDisposed = true; 
    } 
} 

static void Main(string[] args) 
{ 
    var kernel = new StandardKernel(); 

    kernel.Bind<MyServiceType>().ToSelf().InSingletonScope(); 

    var instance = kernel.TryGet<MyServiceType>(); 
    Debug.Assert(instance != null && !instance.IsDisposed); 

    // release the instance 
    kernel.Release(instance); 
    Debug.Assert(instance.IsDisposed); 
    instance = null; 

    // unbind the service 
    kernel.Unbind<MyServiceType>(); 

    // uncomment below for workaround 
    // kernel.Rebind<MyServiceType>().ToConstant((MyServiceType)null); 

    // after unbinding should no longer be able to get an instance of the service 
    instance = kernel.TryGet<MyServiceType>(); 
    Debug.Assert(instance == null); // <---- this is failing! 
} 

回答

2

这是因为Ninject会尝试构建您的对象,即使它没有绑定。如果它有一个无参数的构造函数,它将使用它,否则它将尝试使用容器中的依赖项构造它。

为了证实这一点,即使你跳过MyServiceType的初始绑定,还是做一个TryGet,你会得到一个实例。

或者,你可以尝试解决该实例已绑定和释放后,并声称他们是同一类的不同逸岸实例。

+0

谢谢,这确实是这种情况。我确实尝试了后一种测试,并且我认为出于某种原因绑定仍然被缓存在某处。我猜想我的失败是因为我认为绑定必须存在才能让ninject实例化,但我更喜欢这种行为。 –

+0

@MonroeThomas曾经有一种方法可以控制自己的隐藏自我绑定是通过'NinjectSettings'启用的。我相信它仍然存在,但如果你想关闭它,可能会略微移动。 –

+0

@RubenBartelink谢谢;我会寻找的。 –