Symfony Dependency Injection внедряет новый экземпляр класса

Я использую Symfony / компонент зависимости-инъекции (примечание: не используется полная структура стека)

При регистрации нового сервиса я хочу добавить в конструктор новый экземпляр класса. Пример:

$container->register('session', 'Vendor\Core\Session')
    ->addArgument(new PhpBridgeSessionStorage());

Пример работает очень хорошо, но что если я захочу использовать файлы yml для определения этого сервиса? Что-то вроде:

services:
  session:
    class: Vendor\Core\Session
    arguments: [ new Class\To\Inject ]

Я вынужден определить Class\To\Inject как новый сервис? или создать сервисную фабрику?

3 ответа

Решение

Области применения устарели с 2.8. использование shared: false вместо.

http://symfony.com/doc/current/cookbook/service_container/shared.html

services:
  session:
    class: Vendor\Core\Session
    arguments: [ "@inject.me" ]

  inject.me:
    class: Class\To\Inject
    shared: false

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

<?php

final class ClassFactory
{
   public static function create($class, array $arguments = [])
   {
     return new $class($arguments);
   }
}
  • создать новый сервис

    app.class_factory: class: ClassFactory

  • после внедрения новых классов вот так:

    аргументы: ['@=service("app.class_factory").create("Monolog\Logger")']

Для Symfony >=2.8 вы также можете воспользоваться функцией "автоподключение" -> http://symfony.com/blog/new-in-symfony-2-8-service-auto-wiring

Да, все вводимые вами классы должны быть услугами. Вы можете дать им объем prototype создавать новый экземпляр каждый раз, когда он запрашивается.

Для получения дополнительной информации см.: http://symfony.com/doc/current/cookbook/service_container/scopes.html

Я сам искал этот ответ для библиотеки, которой просто нужно создать некоторые объекты-значения (службы) для других служб, и мне казалось, что все эти службы в YAML (с длинными уникальными именами) загрязняют конфигурацию службы по сравнению с определением объекты значения без имени службы в PHP.

В обычных приложениях это на самом деле не проблема при использовании текущей версии Symfony (3.4+), где все службы по умолчанию являются частными, поскольку контейнер служб заметит себя, если частная служба используется только один раз, а затем встроит ее (так что имя не будет использоваться), в результате получится точно такой же код контейнера службы, как при определении службы без имени в PHP.

Итак, пока вы объявляете все службы закрытыми (или используете значения по умолчанию в Symfony 3.4+), они будут соответствующим образом оптимизированы (и удалены, если не используются).

Другие вопросы по тегам