我目前正在为一个项目测试一些IoC框架,我很想能够使用Ninject 3.
我遇到了一个问题,在我将配置绑定到具体类型的单例之后,我似乎无法在以后有效地取消绑定服务类型。也就是说,StandardKernel.TryGet<T>()
在调用StandardKernel.Unbind<T>()
后返回非空值。请参阅下面的代码段,了解我的确切用法。
这是Ninject 3中的一个错误,还是我缺少的东西?
作为一种解决方法,我可以简单地将具体类型重新绑定为常量null值。但是我更愿意理解,在我回到那个位置之前,我是不是在做什么。
顺便说一下,如果我在单例作用域中指定绑定到具体类型的接口,而不是单行作用域中的自绑定具体类型,则取消绑定将按预期工作。如果这不是一个错误(并且对于额外的业力)你能解释为什么行为存在差异吗?
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!
}
答案 0 :(得分:2)
这是因为Ninject将尝试构造您的对象,即使它没有绑定。如果它有一个无参数构造函数,它将使用它,否则它将尝试使用容器中的依赖项构造它。
为了证明这一点,即使您跳过MyServiceType的初始绑定,仍然执行TryGet,您将获得一个实例。
或者,您可以尝试在绑定和释放实例后对其进行解析,并声明它们实际上是同一类的不同实例。