简体   繁体   中英

Ninject not resolving to a configured singleton when resolving an interface

I have an application that uses Ninject for its DI. I'm adding some new classes and they are not being resolved the way I think they should be.

I have a class Foo that implements an interface ISomething . If I configure the bindings like this:

kernel.Bind<Foo>().ToSelf().InSingletonScope();
kernel.Bind<ISomething>().To<Foo>();

and then do:

var foo1 = kernel.Get<Foo>();
var foo2 = kernel.Get<ISomething>();

the two variables have different instances of the Foo class.

If I change the binding to:

kernel.Bind<Foo>().ToSelf().InSingletonScope();
kernel.Bind<ISomething>().ToMethod(ctx => ctx.Kernel.Get<Foo>());

and then do:

var foo1 = kernel.Get<Foo>();
var foo2 = kernel.Get<ISomething>();

the two variables have the same instance.

My understanding is that in the first case it should resolve the ISomething to Foo , which will in turn resolve to the singleton of itself. Is my understanding incorrect, or is something else wrong? It seems a bit redundant to have to manually resolve it.

When you omit the lifestyle in the registration, by convention, Ninject uses the transient lifestyle. This means that this:

kernel.Bind<ISomething>().To<Foo>();

Is equivalent to:

kernel.Bind<ISomething>().To<Foo>().InTransientScope();

With the addition of the lifestyle, it becomes easier to spot the problem:

kernel.Bind<Foo>().ToSelf().InSingletonScope();
kernel.Bind<ISomething>().To<Foo>().InTransientScope();

Or even more clearly:

kernel.Bind<Foo>()       .To<Foo>().InSingletonScope();
kernel.Bind<ISomething>().To<Foo>().InTransientScope();

Here you see that you are registering Foo both as singleton and transient. This misconfiguration is a common pitfall called Ambiguous Lifestyles :

When multiple registrations with a different lifestyle map to the same component, the component is said to have ambiguous lifestyles. Having one single component with multiple lifestyles will cause instances of that component to be cached in different ways and this can lead to behavior that you might not expect.

Some DI Containers do contain verification mechanisms that you can use to detect this kind of misconfiguration, but all DI Containers that I'm familiar with do allow you to accidentally misconfigure the container this way.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM