Adam
Adam

Reputation: 524

How to get the instance ninject passes into a constructor

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

Answers (2)

Yacoub Massad
Yacoub Massad

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

Adam
Adam

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

Related Questions