Контейнер для инъекций зависимостей против шаблона реестра

Я понимаю, что принцип Injection Dependency основан на развязке кода. Вместо того, чтобы создавать новые экземпляры в классах, вместо этого вы вводите их, что делает их слабо связанными.

Теперь, если мне нужно передать набор объектов, которые будут использоваться несколькими классами в моем приложении, я могу создать контейнер (обычно называемый контейнером инъекции зависимостей).

Это именно то, что я делаю, потому что мне нужно передать объект конфигурации, объект журнала, объект транслятора и т. Д., Которые будут использоваться через несколько экземпляров классов моего приложения. Я передаю весь контейнер через несколько классов, даже если не всем классам нужен доступ ко всем объектам в контейнере. Это привело меня к следующему вопросу: в чем разница, создаю ли глобальный реестр и помещаю туда объекты, а затем возвращаю их как Registry :: getInstance () -> get ('logger'); ? Wether Я использую глобальный реестр или контейнер зависимостей, у класса isntances будет доступ ко всем объектам в контейнере или в реестре, даже если им не нужно видеть / получать доступ ко всем из них.

Заключение: В чем разница, если я передаю контейнер для инъекций зависимостей по моим классам или глобальному реестру?

Я думаю, что здесь отсутствует пункт CompositionRoot . В соответствии с принципом DI, как только вы определяете свои привязки в корне композиции, вы можете использовать ссылку во всем приложении. То есть значение DI Container приносит.

Согласно определению «Корень композиции» является (предпочтительно) уникальным местом в приложении, где модули составлены вместе ».

Я добавлю, что Root Composition также является уникальным местом, где происходят все важные решения о поведении ваших приложений. Это то, что объект использовать в какой ситуации. Это сердце системы OO, где взаимодействие между объектами обеспечивает поведение системы.

Примечание: иногда люди используют реестры разными именами. Обычные, которые я видел как: Локатор, Контекст и Система.

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

Для людей довольно часто путать контейнеры с реестрами.

Контейнер DI – это не то, что вы вводите в класс. Вместо этого это усовершенствование для фабрик: он определяет, что класс Foo требует, чтобы экземпляр Bar был введен в конструктор. Затем, в зависимости от установки, он либо приобретает новый экземпляр Bar либо использует существующий, чтобы обеспечить указанную зависимость.

  • На простой фабрике вам обычно приходится жестко закодировать зависимости, которые будут введены. В этой ситуации, какая фабрика может построить, она ограничена «footprint» конструктора класса.

  • Когда завод использует контейнер DI, он может создавать экземпляры с различными зависимостями. В этой настройке ваши заводы сосредоточены на создании экземпляров, привязанных к определенным классам имен (или других высокоуровневых) классов.

Я согласен с большей частью того, что сказал teresko, и я хотел бы добавить несколько моментов:

  • Если вы считаете, что ваши сервисы распределены между несколькими разными экземплярами, вы можете зарегистрировать их как Singeltons с контейнером, но тогда вам придется подумать о многопоточности, если это проблема для вашего.
  • Всякий раз, когда вы чувствуете, что ваша спина находится напротив стены в сценарии инъекции зависимостей, помните, что фабрики (абстрактный заводский шаблон) почти всегда являются решением.
  • Службы, о которых вы упомянули, кажутся сквозной проблемой, поэтому я бы использовал методы АОП, чтобы избежать раздувания моей кодовой базы с этими проблемами, это сделает код намного более чистым.