Sylius:如何使用自定义控制器创建我自己的自定义资源而不会出现 "can not autowire"-exception?
Sylius: how to create my own Custom Resource with custom controller without getting "can not autowire"-exception?
我想按照 here. After many pitfalls and errors as described blow I looked also at some Sylius plugins and found this one 所述在 Sylius 应用程序中创建我自己的自定义资源,一切正常。
但是,遵循文档和此类示例在我的案例中不起作用。
我是这样定义资源的:
resources.yml
:
app.custody:
driver: doctrine/orm
classes:
model: AppBundle\Entity\CustodyWallet
form: AppBundle\Form\Type\CustodyType
controller: AppBundle\Controller\Shop\CustodyController
routing.yml
:
account_token_custody:
path: /account/custody
methods: [GET, POST]
defaults:
_controller: app.controller.custody:custodyAction
_sylius:
template: "@AppBundle/custody.html.twig"
redirect: sylius_shop_account_dashboard
CustodyController 如下所示:
use AppBundle\Entity\CustodyWallet;
use AppBundle\Form\Type\CustodyType;
use Sylius\Bundle\ResourceBundle\Controller\ResourceController;
use Symfony\Component\Form\Form;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class CustodyController extends ResourceController
{
public function custodyAction(Request $request): Response
{
// .... code .....
}
}
但是,它会导致以下错误:
Cannot autowire service "AppBundle\Controller\Shop\CustodyController":
argument "$metadata" of method
"Sylius\Bundle\ResourceBundle\Controller\ResourceController::__construct()"
references interface
"Sylius\Component\Resource\Metadata\MetadataInterface" but no such
service exists. Did you create a class that implements this interface?
搜索此错误将我带到这个 GitHub 问题,人们建议将此特定控制器的 autowire 设置为 false。所以我做了:
services.yml:
AppBundle\Controller\Shop\CustodyController:
autowire: false
public: true
但是这样调用构造函数时没有任何参数:
Too few arguments to function
Sylius\Bundle\ResourceBundle\Controller\ResourceController::__construct(),
0 passed in
/var/www/var/cache/dev/Container1MQRWcB/getCustodyControllerService.php
on line 16 and exactly 17 expected
我很好奇为什么类似的配置在我上面提到的 CmsPlugin 中有效,但在我的情况下却没有。
我怎样才能做到这一点?
基于此配置
sylius_resource:
resources:
app.custody:
driver: doctrine/orm
classes:
model: AppBundle\Entity\CustodyWallet
controller: AppBundle\Controller\Shop\CustodyController
Sylius 将根据 resource bundle documentation
生成一些服务,包括资源控制器
只需定义控制器 class,它将定义服务并连接正确的构造函数参数。
在这种情况下,它会生成一个id为app.controller.custody
的服务,这个定义可以通过运行 php bin/console debug:container app.controller.custody
.
看到
然后,在services.yaml
中有这个配置
AppBundle\Controller\Shop\CustodyController:
autowire: false
public: true
它定义了另一个未被 Sylius 处理的 ID 为 AppBundle\Controller\Shop\CustodyController
的服务。
即使删除该配置,错误仍然存在,因为在同一页面上有一个 automatic service loading configured, here's another example。
解决方案很简单:从该导入中排除资源控制器:
# config/services.yaml
services:
# 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/{DependencyInjection,Entity,Migrations,Tests,Kernel.php,CustodyController.php}'
如果有很多资源控制器 and/or 可能会添加更多,那么将它们放在一个公共文件夹中并将其添加到 exlude glob 模式可能会更容易,例如:
# config/services.yaml
services:
# 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/{DependencyInjection,Entity,Migrations,Tests,Kernel.php,ResourceController}'
我想按照 here. After many pitfalls and errors as described blow I looked also at some Sylius plugins and found this one 所述在 Sylius 应用程序中创建我自己的自定义资源,一切正常。
但是,遵循文档和此类示例在我的案例中不起作用。
我是这样定义资源的:
resources.yml
:
app.custody:
driver: doctrine/orm
classes:
model: AppBundle\Entity\CustodyWallet
form: AppBundle\Form\Type\CustodyType
controller: AppBundle\Controller\Shop\CustodyController
routing.yml
:
account_token_custody:
path: /account/custody
methods: [GET, POST]
defaults:
_controller: app.controller.custody:custodyAction
_sylius:
template: "@AppBundle/custody.html.twig"
redirect: sylius_shop_account_dashboard
CustodyController 如下所示:
use AppBundle\Entity\CustodyWallet;
use AppBundle\Form\Type\CustodyType;
use Sylius\Bundle\ResourceBundle\Controller\ResourceController;
use Symfony\Component\Form\Form;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class CustodyController extends ResourceController
{
public function custodyAction(Request $request): Response
{
// .... code .....
}
}
但是,它会导致以下错误:
Cannot autowire service "AppBundle\Controller\Shop\CustodyController": argument "$metadata" of method "Sylius\Bundle\ResourceBundle\Controller\ResourceController::__construct()" references interface "Sylius\Component\Resource\Metadata\MetadataInterface" but no such service exists. Did you create a class that implements this interface?
搜索此错误将我带到这个 GitHub 问题,人们建议将此特定控制器的 autowire 设置为 false。所以我做了:
services.yml:
AppBundle\Controller\Shop\CustodyController:
autowire: false
public: true
但是这样调用构造函数时没有任何参数:
Too few arguments to function Sylius\Bundle\ResourceBundle\Controller\ResourceController::__construct(), 0 passed in /var/www/var/cache/dev/Container1MQRWcB/getCustodyControllerService.php on line 16 and exactly 17 expected
我很好奇为什么类似的配置在我上面提到的 CmsPlugin 中有效,但在我的情况下却没有。
我怎样才能做到这一点?
基于此配置
sylius_resource:
resources:
app.custody:
driver: doctrine/orm
classes:
model: AppBundle\Entity\CustodyWallet
controller: AppBundle\Controller\Shop\CustodyController
Sylius 将根据 resource bundle documentation
生成一些服务,包括资源控制器只需定义控制器 class,它将定义服务并连接正确的构造函数参数。
在这种情况下,它会生成一个id为app.controller.custody
的服务,这个定义可以通过运行 php bin/console debug:container app.controller.custody
.
然后,在services.yaml
中有这个配置
AppBundle\Controller\Shop\CustodyController:
autowire: false
public: true
它定义了另一个未被 Sylius 处理的 ID 为 AppBundle\Controller\Shop\CustodyController
的服务。
即使删除该配置,错误仍然存在,因为在同一页面上有一个 automatic service loading configured, here's another example。
解决方案很简单:从该导入中排除资源控制器:
# config/services.yaml
services:
# 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/{DependencyInjection,Entity,Migrations,Tests,Kernel.php,CustodyController.php}'
如果有很多资源控制器 and/or 可能会添加更多,那么将它们放在一个公共文件夹中并将其添加到 exlude glob 模式可能会更容易,例如:
# config/services.yaml
services:
# 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/{DependencyInjection,Entity,Migrations,Tests,Kernel.php,ResourceController}'