Как внедрять экземпляры в контейнер

Дата обновления перевода 2024-07-27

Как внедрять экземпляры в контейнер

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

Например, сервис kernel в Symfony внедряется в контейнер из класса Kernel:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// ...
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\HttpKernel\TerminableInterface;

abstract class Kernel implements KernelInterface, TerminableInterface
{
    // ...

    protected function initializeContainer(): void
    {
        // ...
        $this->container->set('kernel', $this);

        // ...
    }
}

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

Для того, чтобы сделать это, пометьте сервис, как синтетический, в вашей конфигурации определения сервиса:

1
2
3
4
5
# config/services.yaml
services:
    # синтетические сервисы не указывают класс
    app.synthetic_service:
        synthetic: true

Теперь вы можете внедрять экземпляр в контейнер, используя метод Container::set():

1
2
3
// инстанциируйте синтетический сервис
$theService = ...;
$container->set('app.synthetic_service', $theService);