Ninject не разрешается в настроенном синглтоне при разрешении интерфейса - PullRequest
1 голос
/ 31 марта 2020

У меня есть приложение, которое использует Ninject для своего DI. Я добавляю несколько новых классов, и они не решаются так, как я думаю.

У меня есть класс Foo, который реализует интерфейс ISomething. Если я настраиваю привязки следующим образом:

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

и затем выполняю:

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

, то две переменные имеют различных экземпляров класса Foo.

Если я изменю привязку на:

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

, а затем сделаю:

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

, две переменные имеют одинаковый экземпляр.

Насколько я понимаю, в первом случае он должен разрешить от ISomething до Foo, что, в свою очередь, разрешит сам по себе одиночный элемент. Мое понимание неверно, или что-то еще не так? Кажется, немного излишним, чтобы вручную разрешить его.

1 Ответ

3 голосов
/ 31 марта 2020

Когда вы пропускаете образ жизни при регистрации, по соглашению Ninject использует переходный образ жизни. Это означает, что это:

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

Эквивалентно:

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

С добавлением образа жизни становится легче обнаружить проблему:

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

Или еще яснее:

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

Здесь вы видите, что вы регистрируете Foo как синглтон и как переходный процесс. Эта неправильная конфигурация является распространенной ошибкой, называемой Неоднозначные образы жизни :

Когда несколько регистраций с другим образом жизни соответствуют одному и тому же компоненту, компонент, как говорят, имеет неоднозначный образ жизни. Наличие одного компонента с несколькими образами жизни приведет к тому, что экземпляры этого компонента будут кэшироваться различными способами, и это может привести к поведению, которого вы не можете ожидать.

Некоторые контейнеры DI содержат механизмы проверки, которые вы можете используется для обнаружения неправильной конфигурации такого типа, но все знакомые мне DI-контейнеры позволяют случайно неверно конфигурировать этот контейнер.

...