Autowire не работает в компоненте Symfony Dependency Injection

Я использую компонент Symfony Dependency Injection версии 3.4 в моем пользовательском проекте PHP. Мой проект работает на PHP 5.6

"symfony/dependency-injection": "^3.4"

Я определил свой файл services.yaml таким образом, чтобы он содержал следующие определения служб

logger:
  class: Monolog\Logger
  arguments: ["application"]
  autowire: true
  public: true

Monolog\Logger: '@logger'

plugin_context:
  class: MyProject\PluginContext
  autowire: true
  public: true

Я могу подтвердить, что автозагрузка работает и экземпляры обоих классов присутствуют в определении, но класс Logger не подключается автоматически в конструкторе PluginContext. класс определен в следующем коде

use Monolog\Logger;

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

Когда выполняется следующий код, PHP выдает исключение

$container->get("plugin_context");

Catchable fatal error: Argument 1 passed to MyProject\PluginContext::__construct() must be an instance of Monolog\Logger, none given

отсутствует arguments: ["Monolog\Logger"] для plugin_context:? похоже, что вашему конструктору требуется зависимость от регистратора, но она не определена в аргументах содержимого плагина

Noman 03.04.2018 10:25

Ответ @ Smaine ниже о подсказке типа для LoggerInterface верен. Если вы собираетесь использовать autowire, вам необходимо иметь достаточно глубокое понимание того, как это работает, что означает чтение и понимание документы. И научиться использовать такие команды, как «bin / console debug: container --show-private | grep logger», чтобы узнать, какие службы и псевдонимы доступны.

Cerad 03.04.2018 14:41
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
2
2 893
2

Ответы 2

Похоже, что либо содержимое services.yaml не заполнено.

Ваш файл услуг должен быть таким

services:
  logger:
    class: Monolog\Logger
    arguments: ["application"]
    autowire: true
    public: true

  Monolog\Logger: '@logger'

  plugin_context:
    class: MyProject\PluginContext
    autowire: true
    public: true

Измените свой FQCN $logger и используйте этот use Psr\Log\LoggerInterface вместо Monolog\Logger Другое дело, благодаря автонастройке вам не нужно ничего указывать в service.yaml, кроме этого (конфигурация по умолчанию):

_defaults:
    autowire: true      # Automatically injects dependencies in your services.
    autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
    public: false       # Allows optimizing the container by removing unused services; this also means
                        # fetching services directly from the container via $container->get() won't work.
                        # The best practice is to be explicit about your dependencies anyway.

# makes classes in src/ available to be used as services
# this creates a service per class whose id is the fully-qualified class name
App\:
    resource: '../src/*'
    exclude: '../src/{Entity,Migrations,Tests,Kernel.php}'

Док сказал: «Псевдонимы используются основными пакетами, чтобы разрешить автоматическое подключение сервисов. Например, MonologBundle создает службу с идентификатором регистратора. Но он также добавляет псевдоним: Psr \ Log \ LoggerInterface, который указывает на службу регистратора. Вот почему аргументы, типизированные с помощью Psr \ Log \ LoggerInterface, могут быть автоматически подключены », поэтому в вашем случае Psr \ Log \ LoggerInterface является псевдонимом для Monolog https://symfony.com/doc/current/service_container/autowiring.html#using-aliases-to-enable-autowiring

Я использую только компонент Symfony Dependency Injection, и мой проект не основан на фреймворке Symfony. Кроме того, почему я должен использовать LoggerInterface вместо Monolog?

Nisar Ahmed 03.04.2018 15:15

С интерфейсом работать проще, и многие компоненты в Symfony, использующие автоподключение, должны использоваться с интерфейсом symfony.com/doc/current/service_container/….

Smaïne 03.04.2018 15:32

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

Nisar Ahmed 04.04.2018 14:15

Очень хороший вопрос. Мне нужно время, чтобы глубже изучить компонент DependencyInjection.

Smaïne 04.04.2018 14:44

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