在 Symfony 4.4 中覆盖控制器(装饰)- "You have requested a non-existent service"
Overriding Controller in Symfony 4.4 (Decorates) - "You have requested a non-existent service"
我有一个名为 Jason/JasonSticksBundle 的 Bundle,在其中我有一个名为 StickController 的控制器。
我在 Jason/JasonSticksBundle/Resources/config/services.yaml
中定义了一个服务
Jason\JasonSticksBundle\Controller\StickController:
public: true
arguments: []
tags: ['controller.service_arguments']
我的 services.yaml 是通过 JasonSticksExtension->load() 加载的,我的包是在 bundles.php 中注册的。
捆绑包按原样运行良好。
但是
对于这个特定的项目,我想覆盖 StickController 中的一些方法,所以我试图 "decorate" 它。
在我的常规 services.yaml 底部,因此我有以下内容:
App\Controller\StickController:
decorates: Jason\JasonSticksBundle\Controller\StickController
但是我得到这个错误
您请求了一项不存在的服务"Jason\JasonSticksBundle\Controller\StickController"。
最后,如果我 运行
php bin/console debug:container
我可以看到我的服务
Jason\JasonSticksBundle\Controller\StickController Jason\JasonSticksBundle\Controller\StickController
我能想象的是,我的 services.yaml 在我的 StickBundle 注册之前就已经注册了,因此它在正确的时间不存在。但我不知道如何更改它的顺序,或者这是否是一个可行的选择?
感谢任何帮助。
我找到了解决方法,但没有解决。这绝对不是这样做的方法 - 装饰存在是有原因的,我不确定为什么我不能让它工作所以任何建议仍然会受到赞赏。
我的解决方法:
我从我的包 services.yaml 中删除了我的控制器定义,并且我编辑了我的包配置 class 的 ConfigTreeBuilder 以包含一个 scalarNode 字段以允许传递 class 名称- 这个 class 名称将成为覆盖捆绑包的控制器。
然后,为了在不使用 services.yaml 的情况下注册控制器服务,我修改了我的 JasonStickExtension class,并在加载 services.yaml 文件(其他服务仍然需要)后添加了以下内容:
$stickControllerDefinition = $container->findDefinition('Jason\JasonSticksBundle\Controller\StickController');
$stickControllerDefinition->addTag("controller.service_arguments");
$stickDec = $config['stick_controller_class'];
if($stickDec!=null) {
$stickControllerDefinition->setClass($stickDec);
}
这是一种直接的方法,正如我所说,我真的不认为这是正确的方法。
我有一个名为 Jason/JasonSticksBundle 的 Bundle,在其中我有一个名为 StickController 的控制器。
我在 Jason/JasonSticksBundle/Resources/config/services.yaml
中定义了一个服务Jason\JasonSticksBundle\Controller\StickController:
public: true
arguments: []
tags: ['controller.service_arguments']
我的 services.yaml 是通过 JasonSticksExtension->load() 加载的,我的包是在 bundles.php 中注册的。
捆绑包按原样运行良好。
但是
对于这个特定的项目,我想覆盖 StickController 中的一些方法,所以我试图 "decorate" 它。
在我的常规 services.yaml 底部,因此我有以下内容:
App\Controller\StickController:
decorates: Jason\JasonSticksBundle\Controller\StickController
但是我得到这个错误
您请求了一项不存在的服务"Jason\JasonSticksBundle\Controller\StickController"。
最后,如果我 运行
php bin/console debug:container
我可以看到我的服务
Jason\JasonSticksBundle\Controller\StickController Jason\JasonSticksBundle\Controller\StickController
我能想象的是,我的 services.yaml 在我的 StickBundle 注册之前就已经注册了,因此它在正确的时间不存在。但我不知道如何更改它的顺序,或者这是否是一个可行的选择?
感谢任何帮助。
我找到了解决方法,但没有解决。这绝对不是这样做的方法 - 装饰存在是有原因的,我不确定为什么我不能让它工作所以任何建议仍然会受到赞赏。
我的解决方法:
我从我的包 services.yaml 中删除了我的控制器定义,并且我编辑了我的包配置 class 的 ConfigTreeBuilder 以包含一个 scalarNode 字段以允许传递 class 名称- 这个 class 名称将成为覆盖捆绑包的控制器。
然后,为了在不使用 services.yaml 的情况下注册控制器服务,我修改了我的 JasonStickExtension class,并在加载 services.yaml 文件(其他服务仍然需要)后添加了以下内容:
$stickControllerDefinition = $container->findDefinition('Jason\JasonSticksBundle\Controller\StickController');
$stickControllerDefinition->addTag("controller.service_arguments");
$stickDec = $config['stick_controller_class'];
if($stickDec!=null) {
$stickControllerDefinition->setClass($stickDec);
}
这是一种直接的方法,正如我所说,我真的不认为这是正确的方法。