2017-01-04 3 views
2

Я видел фреймворки, такие как Ninject, а также сообщения на Stack, говорящие о самообучении при использовании инфраструктур инъекций зависимостей, как в приведенном ниже коде.Что такое самообучение в контейнере IoC?

Bind<Samurai>().To<Samurai>(); 

Они даже пойти в той степени, имеющих специальный синтаксис для этого:

Bind<Samurai>().ToSelf(); 

Почему вы хотите, чтобы связать тип к себе? Я не вижу каких-либо практических приложений для того, где это может быть полезно и помогает уменьшить зависимости в коде. Разве это не означает, что ссылка на тип просто решила бы сама по себе?

+0

Это просто делает фреймворк осведомленным об объекте, который будет разрешен. Например, «Bind () .ToSelf() .InSingletonScope();' позволяет контейнеру знать, что тип должен быть разрешен как одноэлементный. В целом это всего лишь часть регистрации типов с контейнером. – Nkosi

+0

Но зачем это нужно решать? если мы передаем экземпляр в конструктор, я не вижу необходимости его разрешать. Также используется '.InSingletonScope()', поэтому нам не нужно самостоятельно реализовать шаблон singleton? – oflad

+0

, потому что контейнер - это экземпляр экземпляров экземпляров, и ему нужно знать, какие типы он может создать и как обрабатывать или обрабатывать их.Вы понимаете принцип инверсии зависимостей? вся цель контейнера состоит в том, чтобы не делать это самостоятельно – Nkosi

ответ

4

При применении зависимостей Инъекции и соблюдения требований Dependency Inversion Principle общий совет: to program to interfaces, not implementations. Именно поэтому большая часть времени вы увидите привязки, которые идут от абстракции к реализации:

Bind<IWarrior>().To<Samurai>(); 

Это означает, что компоненты будут принимать зависимость от IWarrior во время компиляции, и мы впрыснуть Samurai во время выполнения.

При определенных условиях, однако, имеет смысл отображать от конкретного компонента к себе. Другими словами, если «кто-то» запрашивает Samurai, мы предоставляем его Samurai.

Наиболее известный случай при разрешении типов корней. Типы корней - это вершина графика зависимости; корневые типы разрешаются непосредственно из контейнера. Все остальные типы являются прямыми или косвенными зависимостями корневого типа.

Часто вы обнаружите, что эти корневые типы разрешены конкретными типами и часто мы имеем дело с интерфейсом пользовательского интерфейса. Примерами таких являются веб-формы Page s, MVC Controller s, веб-API ApiController s и т. Д.

Большинство контейнеров DI позволяют разрешать конкретные незарегистрированные типы в любом случае. Это может заставить вас поверить, что самообучение избыточно, но это не всегда так. Добавление такого привязки явно позволяет контейнеру узнать о существовании такой привязки. Это имеет преимущество при использовании диагностических возможностей контейнера (если имеется) для сканирования графов объектов для ошибок. В случае отсутствия такой функции обычно можно проводить итерацию известных регистраций и выполнять некоторую проверку внутри единичного теста. Для того чтобы такая проверка имела смысл при повторной регистрации контейнера, все корневые типы должны быть зарегистрированы в контейнере. В противном случае этот процесс проверки приведет к ложным отрицаниям.

Другая причина, по которой вы хотите рассказать контейнер DI о самообучении, заключается в том, что контейнер не разрешает разрешать незарегистрированные типы или когда вам нужен тип, который должен быть зарегистрирован в другом стиле жизни, чем стиль жизни по умолчанию в контейнере. В большинстве контейнеров вы получите экземпляр Transient, если тип не зарегистрирован.