Reputation: 524
I don't understand this behaviour of ninject singletons. Here's a simple example.
void Main()
{
IKernel kernel = new StandardKernel();
kernel.Bind<IB>().To<B>().InSingletonScope();
kernel.Bind<B>().To<B>().InSingletonScope();
C c = kernel.Get<C>();
B b = kernel.Get<B>();
B b2 = kernel.Get<B>();
ReferenceEquals(c.b, b); //false
ReferenceEquals(b, b2); //true
}
public interface IB
{ }
public class B : IB
{ }
public class C
{
public IB b;
public C(IB b)
{
this.b = b;
}
}
I don't understand why ReferenceEquals(c.b, b)
returns false.
I'd have assumed that if I declare an object as a singleton then ninject would use only a single instance of that object but that appears to not be the case.
Based on my testing it appears to use one instance for constructor injection, and one instance to return to me when I call kernel.Get
.
What I'd like is for kernel.Get
to return to me the same instance that was used for constructor injection. Is this possible?
Upvotes: 2
Views: 893
Reputation: 27871
Class C
depends on IB
, not B
.
If you do something like this:
IB ib = kernel.Get<IB>();
And compare that with c.b like this:
var eq = ReferenceEquals(c.b, ib);
You would get true
.
Each registration that you did (B
and IB
) give you a different singleton.
If you want to have the same singleton, you can do a single registration like this:
kernel.Bind<IB,B>().To<B>().InSingletonScope();
Upvotes: 4
Reputation: 524
I just solved my own question.
It's because I'm calling kernel.Get
on B
not IB
void Main()
{
IKernel kernel = new StandardKernel();
kernel.Bind<IB>().To<B>().InSingletonScope();
kernel.Bind<B>().To<B>().InSingletonScope();
C c = kernel.Get<C>();
B b = kernel.Get<B>();
B b2 = kernel.Get<B>();
IB b3 = kernel.Get<IB>();
ReferenceEquals(c.b, b); //false
ReferenceEquals(c.b, b3); //true
ReferenceEquals(b, b2); //true
}
Upvotes: 1