Php 通过“向控制器添加服务”;容器。服务“用户”;没有按预期工作
我正在尝试使用控制器上的Php 通过“向控制器添加服务”;容器。服务“用户”;没有按预期工作,php,symfony,fosrestbundle,Php,Symfony,Fosrestbundle,我正在尝试使用控制器上的container.service\u subscriber标记使某些服务可用,而无需通过构造函数注入它们。在我们的项目中,我们不想使用自动布线,也不能使用自动配置选项 控制器的结构如下: 我有一个baseBaseController,它从FOSRestBundle的AbstractFOSRestController扩展而来,FOSRestBundle对我的所有控制器都有一些常用的方法。该服务将用作我的其他控制器的父控制器 服务定义如下所示: WM\ApiBundle\C
container.service\u subscriber
标记使某些服务可用,而无需通过构造函数注入它们。在我们的项目中,我们不想使用自动布线
,也不能使用自动配置选项
控制器的结构如下:
我有一个baseBaseController
,它从FOSRestBundle的AbstractFOSRestController
扩展而来,FOSRestBundle对我的所有控制器都有一些常用的方法。该服务将用作我的其他控制器的父控制器
服务定义如下所示:
WM\ApiBundle\Controller\BaseController:
class: WM\ApiBundle\Controller\BaseController
abstract: true
arguments:
- "@service1"
- "@service2"
- ...
WM\ApiBundle\Controller\UserController:
parent: WM\ApiBundle\Controller\BaseController
public: true
#autowire: true
class: WM\ApiBundle\Controller\UserController
tags:
- { name: 'container.service_subscriber'}
- { name: 'container.service_subscriber', key: 'servicexyz', id: 'servicexyz' }
/**
* User controller.
*/
class UserController extends AbstractCRUDController implements ClassResourceInterface
{
public static function getSubscribedServices()
{
return array_merge(parent::getSubscribedServices(), [
'servicexyz' => ServiceXYZ::class,
]);
}
.......
}
该类如下所示:
WM\ApiBundle\Controller\BaseController:
class: WM\ApiBundle\Controller\BaseController
abstract: true
arguments:
- "@service1"
- "@service2"
- ...
WM\ApiBundle\Controller\UserController:
parent: WM\ApiBundle\Controller\BaseController
public: true
#autowire: true
class: WM\ApiBundle\Controller\UserController
tags:
- { name: 'container.service_subscriber'}
- { name: 'container.service_subscriber', key: 'servicexyz', id: 'servicexyz' }
/**
* User controller.
*/
class UserController extends AbstractCRUDController implements ClassResourceInterface
{
public static function getSubscribedServices()
{
return array_merge(parent::getSubscribedServices(), [
'servicexyz' => ServiceXYZ::class,
]);
}
.......
}
我遇到的问题是,如果我设置了autowire:false
,它总是自动设置完整的容器,并带有相应的弃用消息(因为我不是自己设置的):
不推荐用户:自Symfony 4.2以来,不推荐自动注入“WM\APIBULND\Controller\UserController”的容器。将其配置为服务
设置autowire:true
Symfony确实尊重container.service\u订户
标记,并且只设置部分容器(ServiceLocator),这也将解决弃用消息。在这种情况下,我希望自动布线不会有任何区别,因为我明确地告诉服务应该有哪些其他服务。我是否使用了错误的标记,或者在理解如何向控制器订阅服务时遇到了一般性问题?基本问题是内置服务订户功能只会将服务定位器注入构造函数。扩展AbstractController的传统控制器使用autoconfigure基本上覆盖了这一点,并使用setContainer代替构造函数
# ApiBundle/Resources/config/services.yaml
services:
_defaults:
autowire: false
autoconfigure: false
Api\Controller\UserController:
public: true
tags: ['container.service_subscriber']
结果:
API Index Controller Symfony\Component\DependencyInjection\Argument\ServiceLocator
指示服务定位器(与正在注入的全局容器相反)
您还可以将服务配置为使用setContainer方法,并消除对构造函数的需要。任何一种方法都会奏效
Api\Controller\UserController:
public: true
tags: ['container.service_subscriber']
calls: [['setContainer', ['@Psr\Container\ContainerInterface']]]
问题的解决方案是通过调用
setContainer
来扩展控制器的服务定义,以注入'@Psr\Container\ContainerInterface'
服务:
WM\ApiBundle\Controller\BaseController:
class: WM\ApiBundle\Controller\BaseController
abstract: true
arguments:
- "@service1"
- "@service2"
- ...
calls:
- ['setContainer', ['@Psr\Container\ContainerInterface']]
WM\ApiBundle\Controller\UserController:
parent: WM\ApiBundle\Controller\BaseController
public: true
class: WM\ApiBundle\Controller\UserController
tags:
- { name: 'container.service_subscriber'}
- { name: 'container.service_subscriber', key: 'servicexyz', id: 'servicexyz' }
这将为我提供一个ServiceLocator
容器,它只包含已注册的服务,而不包含完整的容器,而不使用autowire
选项。旁注:设置
@service\u容器将注入完整的容器
为了完整起见,symfony项目中已经有一个讨论过这一点的项目。感谢您的时间和回复。但这不正是与事实相反吗?它甚至说如果我不想使用自动配置,我应该使用标签。还测试了仅启用了autoconfigure而不会改变行为的情况,使其达到预期效果(或至少据我所知)的唯一方法是启用autowire。找到了问题的解决方案。实际上,symfony项目中已经有了。我缺少的是对['setContainer',['@Psr\Container\ContainerInterface']]
的调用,这将为我提供服务定位器。我曾经用服务容器
试过一次,但它总是包含完整的容器,所以这可能会让我感到困惑。酷。我试图找出如何使用呼叫,但从未尝试使用Psr ContainerInterface。我把它作为答案的一个选项。