问题
I'm currently testing some IoC frameworks for a project, and I'd love to be able to use Ninject 3.
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.
Is this a bug in Ninject 3, or is there something I'm missing?
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!
}
回答1:
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.
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.
来源:https://stackoverflow.com/questions/12398145/how-to-unbind-a-concrete-self-bound-singleton-binding-in-ninject-3