Symfony 自动装配/自动配置不起作用

时间:2021-07-03 21:39:47

标签: php symfony dependency-injection symfony5

我创建了一个 symfony 5.3 api。 我的计划是通过“EntityManagerInterface”注入“EntityManager”。

出现的错误:

Could not resolve argument $entityManager of "app\controller\createuseraccountcontroller()", maybe you forgot to register the controller as a service or missed tagging it with the "controller.service_arguments"?

我的 services.yaml

parameters:

services:
    # default configuration for services in *this* file
    _defaults:
        autowire: true      # Automatically injects dependencies in your services.
        autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.

    # 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/'
            - '../src/Entity/'
            - '../src/Kernel.php'
            - '../src/Tests/'

我在 src/Controller/ 中的 CreateUserAccountController.php:

<?php
declare(strict_types=1);

namespace App\Controller;

use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class CreateUserAccountController
{
    private EntityManagerInterface $entityManager;

    function __construct(EntityManagerInterface $entityManager)
    {
        $this->entityManager = $entityManager;
    }

    #[Route('/user/create', name: 'create_user_account')]
    public function __invoke(): Response
    {
        return new Response('hello world');
    }
}

我的 composer.json:

{
    "type": "project",
    "license": "proprietary",
    "minimum-stability": "stable",
    "prefer-stable": true,
    "require": {
        "php": "8.0.*",
        "ext-ctype": "*",
        "ext-iconv": "*",
        "composer/package-versions-deprecated": "1.11.99.2",
        "doctrine/doctrine-bundle": "^2.4",
        "doctrine/doctrine-migrations-bundle": "^3.1",
        "doctrine/orm": "^2.9",
        "phpseclib/phpseclib": "^3.0",
        "symfony/console": "5.3.*",
        "symfony/dependency-injection": "5.3.*",
        "symfony/dotenv": "5.3.*",
        "symfony/flex": "^1.3.1",
        "symfony/framework-bundle": "5.3.*",
        "symfony/proxy-manager-bridge": "5.3.*",
        "symfony/runtime": "5.3.*",
        "symfony/yaml": "5.3.*"
    },
    "require-dev": {
        "symfony/maker-bundle": "^1.31",
        "symfony/stopwatch": "5.3.*"
    },
    "config": {
        "optimize-autoloader": true,
        "preferred-install": {
            "*": "dist"
        },
        "sort-packages": true
    },
    "autoload": {
        "psr-4": {
            "App\\": "src/"
        }
    },
    "autoload-dev": {
        "psr-4": {
            "App\\Tests\\": "tests/"
        }
    },
    "replace": {
        "symfony/polyfill-ctype": "*",
        "symfony/polyfill-iconv": "*",
        "symfony/polyfill-php72": "*"
    },
    "scripts": {
        "auto-scripts": {
            "cache:clear": "symfony-cmd",
            "assets:install %PUBLIC_DIR%": "symfony-cmd"
        },
        "post-install-cmd": [
            "@auto-scripts"
        ],
        "post-update-cmd": [
            "@auto-scripts"
        ]
    },
    "conflict": {
        "symfony/symfony": "*"
    },
    "extra": {
        "symfony": {
            "allow-contrib": false,
            "require": "5.3.*"
        }
    }
}

我知道我不使用 Manager,但它对我不起作用。 我使用的网络服务器:symfony cli webserver

有没有人知道问题出在哪里?

1 个答案:

答案 0 :(得分:3)

这实际上是一个有点有趣的边缘情况。

最重要的是,autowire 将您的控制器服务定义为私有的。这反过来意味着控制器解析器只是简单地新建控制器,而不是从容器中拉出它。因此缺少参数错误消息。

请注意,您的控制器没有扩展 AbstractController。 如果是,那么自动配置会知道它是一个控制器并最终将其公开。一切都会好起来的。

在 5.3 之前,services.yaml 文件包含:

    App\Controller\:
        resource: '../src/Controller/'
        tags: ['controller.service_arguments']

这些行会自动将控制器目录中的任何内容定义为控制器。大多数时候它们是不需要的,因为大多数控制器都扩展了 AbstractController。这就是为什么这些行最终在 5.3 中被删除的原因。

因此,如果您真的不想扩展 AbstractController,请将这些行重新添加进去。您可以使用 bin/console debug:container CreateUserAccountController 来查看发生了什么。

最后,您还可以选择简单地手动将控制器服务定义为公共服务。类似的东西:

services:

    App\Controller\CreateUserAccountController:
        public: true
        tags: ['controller.service_arguments'] # optional
相关问题