Я использую компонент 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
Похоже, что либо содержимое 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 создает сервис с идентификатором 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