Symfony 3.4.8服务自动装配问题:第三方接口无法注入
我目前在用Symfony 3.4.8版本,有个配置在Symfony 3.3里运行完全正常,但升级到3.4后遇到了下面的错误:
Cannot autowire service "ProblemBundle\EntityManager\ProblemManager": argument "$paginator" of method "__construct()" references interface "Knp\Component\Pager\PaginatorInterface" but no such service exists. Did you create a class that implements this interface?
相关代码如下:
ProblemManager.php
public function __construct(PaginatorInterface $page){}
app/config/services.yml
# Learn more about services, parameters and containers at # https://symfony.com/doc/current/service_container.html parameters: #parameter_name: value services: # default configuration for services in *this* file _defaults: # automatically injects dependencies in your services autowire: true # automatically registers your services as commands, event subscribers, etc. autoconfigure: true # this means you cannot fetch services directly from the container via $container->get() # if you need to do this, you can override this setting on individual services public: true # makes classes in src/AppBundle available to be used as services # this creates a service per class whose id is the fully-qualified class name # add more services, or override services that need manual wiring # AppBundle\Service\ExampleService: # arguments: # $someArgument: 'some_value' UserBundle\Controller\: resource: '../../src/UserBundle/Controller' public: true autowire: true tags: ['controller.service_arguments'] UserBundle\EntityManager\UserManager: autowire: true ProblemBundle\EntityManager\ProblemManager: autowire: true public: true
请问怎么配置自动装配才能支持所有服务(包括第三方Bundle)?
别急,这个问题其实是Symfony 3.4和3.3在处理第三方服务自动装配时的小差异导致的。KnpPaginatorBundle的PaginatorInterface对应的服务,在3.4版本里默认没有被自动关联为接口的实现,所以容器找不到它。
你可以试试下面几个步骤来解决:
先确认KnpPaginatorBundle已正确安装并启用
检查一下app/AppKernel.php里有没有注册这个Bundle:new Knp\Bundle\PaginatorBundle\KnpPaginatorBundle(),如果没加的话,添加上之后记得清一下缓存(
php bin/console cache:clear)。手动为接口添加服务别名
在你的services.yml中,添加一个别名配置,把Knp\Component\Pager\PaginatorInterface指向KnpPaginator提供的实际服务:services: # ... 保留你原有的其他配置 ... Knp\Component\Pager\PaginatorInterface: '@knp_paginator'这样自动装配就能识别到接口对应的服务了——Symfony会通过这个别名找到
knp_paginator这个第三方服务,进而完成依赖注入。关于全局自动配置的补充说明
你的_defaults里已经开启了autoconfigure: true,这个设置没问题,但第三方Bundle的服务不一定都继承了全局的自动配置规则。不过上面的别名方法已经能直接解决当前问题,因为它直接把接口和具体服务绑定了起来。
如果之后你还遇到其他第三方服务的自动装配问题,都可以用这种给接口添加服务别名的方式处理:只要找到第三方Bundle提供的服务ID,再把它和对应的接口关联起来就好。
内容的提问来源于stack exchange,提问作者lcp0578

