Несмотря на то, что создание объекта в контейнере через new и c пустым конструктором является хорошей практикой, в конце концов вы можете вынести в отдельный метод специального класса создание всех необходимых зависимостей и зарегистрировать его выполнение в контейнере, несмотря на это есть способы разрешения зависимостей не прибегая к созданию отдельного класса-обёртки.
В случае возникновения необходимости переиспользовать сервис из контейнера для инициализации другого сервиса в контейнере обратимся к возможностям, которые даёт внедрение зависимостей. В классе App\Bootstrap\ContainerFactory эти методы доступны, как и в отдельном специальном классе для создания контейнера.
Например, необходимо проинициализировать конструктор сервиса в контейнере. Для этого в теле оператора match класса App\Bootstrap\ContainerFactory нужно добавить примерно такое соответствие:
Теперь в конструктор класса DemoService будет попадать текущий сервис ExampleService как он определен в контейнере. Все зависимости, не указанные явно, в используемом примере будут разрешены автоматически (вариант 2).
Важно следить за тем, чтобы зависимости не зациклились, это может быть в случае если при инициализации объекта в контейнере он повторно обращается в контейнер для инициализации этого же объекта.
Более сложный пример:
Подобным образом в контейнер фреймворка, несмотря на его кажущуюся простоту, можно добавлять различные взаимозависимые сервисы.
По умолчанию во фреймворке не допускается добавление сервисов после инициализации контейнера. Но при переопределении метода getSingleton() на публичный в классе ContainerFactory появляется возможность добавлять в контейнер объекты в пользовательском коде через этот статический метод. Образец модификации класса:
Из примера видно, что также добавлена поддержка отложенной инициализации через callable тип и его обработчик.