如何在Ninject 3中取消绑定具体的自绑定单例绑定? [英] How to unbind a concrete self-bound singleton binding in Ninject 3?

查看:68
本文介绍了如何在Ninject 3中取消绑定具体的自绑定单例绑定?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在为一个项目测试一些IoC框架,我希望能够使用Ninject3.

I'm currently testing some IoC frameworks for a project, and I'd love to be able to use Ninject 3.

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

I'm running into an issue where after I configure a binding to a concretely typed singleton, I can't seem to effectively unbind the service type later on. That is, StandardKernel.TryGet<T>() returns a non-null value after calling StandardKernel.Unbind<T>(). See the snippet below for my exact usage.

这是Ninject 3中的错误,还是我缺少了什么?

Is this a bug in Ninject 3, or is there something I'm missing?

作为一种解决方法,我可以简单地将具体类型重新绑定为恒定的null值.但是我宁愿在回退到那个位置之前先了解一下自己是否在做些鬼事.

As a workaround, I can simply rebind the concrete type to a constant null value. But I'd prefer to understand if I'm not grokking something before I fallback to that position.

顺便说一句,如果我指定了绑定到单例作用域中的具体类型的接口,但未指定单例作用域中的自绑定具体类型的接口,则解除绑定将按预期工作.如果这不是一个错误(为了增加业力),您能解释一下为什么行为有所不同吗?

By the way, unbinding works as expected if I specify an interface bound to a concrete type in singleton scope, but not for a self bound concrete type in singleton scope. If this is not a bug (and for extra karma) can you explain why there is a difference in behaviour?

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!
}

推荐答案

这是因为Ninject会尝试构造您的对象,即使该对象未绑定也是如此.如果它具有无参数构造函数,则将使用该构造函数,否则它将尝试使用容器中的依赖项来构造它.

This is because Ninject will attempt to construct your object even if it is not bound. If it has a parameterless constructor, it will use that, otherwise it will try to construct it using dependencies found in the container.

为了向自己证明这一点,即使您跳过MyServiceType的初始绑定,并且仍然执行TryGet,也将获得一个实例.

To prove this to yourself, even if you skip the initial binding of MyServiceType, and still do a TryGet, you will get an instance.

或者,您可以在绑定和释放实例后尝试解析该实例,并断言它们实际上是同一类的不同实例.

Alternatively, you can try resolving the instance after it has been bound and released, and assert that they are infact different instances of the same class.

这篇关于如何在Ninject 3中取消绑定具体的自绑定单例绑定?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆