Zend Service Manager в качестве DI-контейнера Zend Expressive 3

При установке Zend Expressive можно выбрать разные реализации управления зависимостями. У Zend есть и собственный контейнер - Zend Service Manager.

Для его настройки в конфигурации приложения есть отдельный раздел:

'dependencies' => [
        'aliases' => [
            Fully\Qualified\ClassOrInterfaceName::class => Fully\Qualified\ClassName::class,
        ],
        'invokables' => [
            Fully\Qualified\InterfaceName::class => Fully\Qualified\ClassName::class,
        ],
        'factories'  => [
            Fully\Qualified\ClassName::class => Fully\Qualified\FactoryName::class,
        ],

Как видно из примера, есть несколько видов зависимостей, которые могут быть в контейнере:

  • aliases
  • invokable
  • factories

Invokables (Вызываемые)

Это массив вида “название_сервиса” => “класс”. Т.е. создается объект класса через оператор new, помещается как сервис в контейнер. Обычно название сервиса совпадает с назанием класса.

Factories (Фабрики)

Это массив записей вида “названи_сервиса” => “класс фабрики”

Если конструктор объекта требует параметров или объект перед использованием требует некоторой подготовки (напр., определение некоторых переменных) - используется фабрика.

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

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

Aliases (Псевдонимы)

Массив записей вида “название_сервиса” => “название_другого_сервиса”

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

  1. создать два одинаковых класса и при необходимости вносить изменения в оба
  2. можно создать один класс и задать псевдоним (другое имя) класса.

Второй путь более оптимальный. Теоретически, работает это так (могу быть не прав): при запросе сервиса типа alias среди уже объявленных сервисов (invokables, factories) ищется сервис, к которому объявлен псевдоним (циклически раскрывая сссылки), либо выдается копия оригинального объекта.

С этим еще надо поразбираться.

Евгений Вдовенко
Евгений Вдовенко

Физик по образованию, занимаюсь веб-разработкой на PHP с 2013 года. Нравится ковырятся в Zend Framework/Expressive и Joomla CMS/Framework. В процессе разборок с Python. Подумываю посмотреть Go. Считаю PostgreSQL крутым продуктом и внедряю его везде, где могу.