首页 文章

Autowire无法在Symfony的依赖注入组件中工作

提问于
浏览
1

我在我的自定义PHP项目中使用Symfony的Dependency Injection组件版本3.4 . 我的项目在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

我可以确认自动加载是否正常,并且定义中存在两个类的实例,但是在PluginContext构造函数中没有自动装配Logger类 . 该类在以下代码中定义

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

2 回答

  • 0

    似乎 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}'
    

    Doc说:“核心捆绑包使用别名来允许服务自动装配 . 例如,MonologBundle创建一个id为logger的服务 . 但它还添加了一个别名:Psr \ Log \ LoggerInterface,它指向 Logger 服务 . 这就是为什么Psr \ Log \ LoggerInterface类型提示的参数可以自动装配»所以在你的情况下,Psr \ Log \ LoggerInterface是Monolog的别名https://symfony.com/doc/current/service_container/autowiring.html#using-aliases-to-enable-autowiring

相关问题