Dependency Injection Container

121
27 июня 2021, 01:40

Подскажите пожалуйста, при использовании DI-контейнера возникло несколько вопросов:

  1. Должен ли DI-контейнер быть единым для всего приложения ?

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

Например, у меня есть модуль Order, в котором много классов, разных ajax-обработчиков файлов и т.д. Можно ли во всех файлах модуля использовать сервисы контейнера ?

на каком этапе приложения (или модуля) нужно добавлять сервисы в контейнер, ведь нельзя же в любом файле модуля добавлять сервисы, т.к. при попытке получения сервиса из контейнера, может сервиса там не оказаться, т.к. на текущем этапе его там еще нет. Следовательно, нужно при запуске определенного модуля заполнять контейнер сервисами ?

  1. Если вышенаписанное правда, и для целого модуля нужно использовать единый контейнер с свервисами, то как тогда будут все файлы видеть контейнер ? Контейнер должен быть глобальным ? Иили singleton ?

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

Желательно не рассматривать какую-то конкретную реализацию контейнера.

Answer 1
  1. Да,контейнер един и все сервисы создаются через него; Добавление происходит на этапе запуска приложения, то есть в приложении где-то есть единая точка входа, там и создается контейнер и регистрируются все возможные зависимости;
  2. Контейнер не видят все сервисы, это он видет их все. То есть в контейнере зарегистрированы все сервисы и он их создает. Обычно Сервисам не нужно к нему обращаться, т.к. все, что им нужно, все их зависимости и параметры, им передает контейнер через конструктор при создании. Иногда может возникнуть необходимость какому-то сервису обратиться к контейнеру, тогда этот контейнер может передать сам себя через конструктор, если сервис его запрашивает. То есть все сервисы все получают через конструктор автоматически, в том числе и сервис контейнера. К примеру есть у вас модуль order, которому нужно куча зависимостей для своей работы, на старте приложения мы регистрируем и сам этот Order и все нужные ему сервисы в контейнере, после чего просто запрашиваем сам Order у контейнера что-то вроде

    order = Container.GetService(Order);
    И получаем полностью готовый order, со всеми его зависимостями, созданные автоматически.

Пример класса Order, которому нужен logger:

class Order
{
$private $logger;
    public function __construct(Logger $logger) {
$this->logger = $logger;
}
}

И после этого в любом месте можно им воспользоваться

$this->logger.LogInfo();

Если же вам захотелось получить логгер из контейнера, что является скорее плохой практикой, то в конструктор может быть передан непосредственно контейнер

class Order
{
$private $logger;
private $container;
    public function __construct(Container $container) {
$this->container =$container;
// И где угодно можем получить сервис
$this->logger = $this->container.GetService(Logger);
}
}
READ ALSO
Php Language Selector

Php Language Selector

Имеем вот такой селектор,

119
Динамическое изменение select в yii2

Динамическое изменение select в yii2

Вообщем у меня возникла такая проблема мне надо изменять значения select основываясь на другом select, у меня есть форма вот её часть:

98
Как отсортировать товар по рейтингу категории с сохранения id laravel

Как отсортировать товар по рейтингу категории с сохранения id laravel

Есть таблица с товарами и таблица с категориями, у категорий есть рейтинг Нужно отсортировать товар по рейтингу категорий Вот, что у меня...

82
Hе переопределяет путь к PHP on MAMP

Hе переопределяет путь к PHP on MAMP

у меня на данный момент стоит php 71

107