Autowire не работает в компоненте внедрения зависимостей Symfony

Я использую компонент 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

1

Решение

Похоже, что либо содержимое 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
0

Другие решения

Измени свой 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 создает сервис с идентификатором logger. Но он также добавляет псевдоним: Psr \ Log \ LoggerInterface, который указывает на службу ведения журнала. Вот почему аргументы с подсказками типа Psr \ Log \ LoggerInterface могут быть подключены автоматически », так что в вашем случае Psr \ Log \ LoggerInterface является псевдонимом для Monolog. https://symfony.com/doc/current/service_container/autowiring.html#using-aliases-to-enable-autowiring

0