Sylius:如何使用自定义控制器创建自己的自定义资源,而不会出现“无法自动装配”异常的情况?

时间:2019-11-24 15:50:52

标签: symfony sylius sylius-resource

我想按照here的描述在Sylius应用程序中创建自己的自定义资源。在经历了描述的许多陷阱和错误之后,我还查看了一些Sylius插件,发现this one一切正常。

但是,在我的案例中,遵循Docs和此类示例将无效。

我以这种方式定义了资源:

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 .....
    }
}

但是,它导致以下错误:

  

无法自动连线服务“ AppBundle \ Controller \ Shop \ CustodyController”:   方法的参数“ $ metadata”   “ Sylius \ Bundle \ ResourceBundle \ Controller \ ResourceController :: __ construct()”   参考界面   “ Sylius \ Component \ Resource \ Metadata \ MetadataInterface”,但没有此类   服务存在。您是否创建了实现此接口的类?

搜索此错误使我陷入GitHub问题,人们建议为此特定Controller将autowire设置为false。所以我做到了:

services.yml:

AppBundle\Controller\Shop\CustodyController:
    autowire: false
    public: true

但是通过这种方式,构造函数的调用没有任何参数:

  

函数的参数太少   Sylius \ Bundle \ ResourceBundle \ Controller \ ResourceController :: __ construct(),   0传入   /var/www/var/cache/dev/Container1MQRWcB/getCustodyControllerService.php   在第16行,恰好是17行

我很好奇为什么在上面提到的CmsPlugin中可以使用类似的配置,但在我的情况下却不能。

我该如何实现?

1 个答案:

答案 0 :(得分:3)

基于此配置

sylius_resource:
    resources:
        app.custody:
            driver: doctrine/orm
            classes:
                model: AppBundle\Entity\CustodyWallet
                controller: AppBundle\Controller\Shop\CustodyController

Sylius将根据resource bundle documentation

生成一些服务,包括资源控制器。

只需定义控制器类,它将定义服务并连接正确的构造方法参数。

在这种情况下,它将生成一个ID为app.controller.custody的服务,可以通过运行php bin/console debug:container app.controller.custody来看到其定义。

然后,在services.yaml中有此配置

AppBundle\Controller\Shop\CustodyController:
    autowire: false
    public: true

定义ID为AppBundle\Controller\Shop\CustodyController且未被Sylius处理的另一项服务。

即使删除了该配置,由于配置了automatic service loading,错误仍然存​​在,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}'

如果有许多资源控制器和/或可能要添加的资源控制器,则将它们放置在公用文件夹中并将其添加到排除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}'