Skip to content
Advertisement

Symfony autowire/autoconfigure not working

I created a symfony 5.3 api. My plan is to inject the “EntityManager” via “EntityManagerInterface”.

Error that comes:

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

My 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/'

My CreateUserAccountController.php in src/Controller/:

<?php
declare(strict_types=1);

namespace AppController;

use DoctrineORMEntityManagerInterface;
use SymfonyComponentHttpFoundationResponse;
use SymfonyComponentRoutingAnnotationRoute;

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');
    }
}

My 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.*"
        }
    }
}

I know that I dont use the Manager, but it doesn´t work for me. The webserver I use: symfony cli webserver

Has anyone a idea, where the problem is?

Advertisement

Answer

This is actually a somewhat interesting edge case.

The bottom line is that autowire is defining your controller service as private. This in turn means the controller resolver is simply new’ing the controller instead of pulling it from the container. Hence the missing argument error messages.

Notice that your controller does not extend AbstractController. If it did then autoconfigure would know that it is a controller and end up making it public. All would be well.

Prior to 5.3, the services.yaml file contained:

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

Those lines would automatically define anything in the controller directory as a controller. Most of the time they were not needed since most controllers extend AbstractController. Which is why the lines ended up being dropped in 5.3.

So if you really don’t want to extend AbstractController then add those lines back in. You can use bin/console debug:container CreateUserAccountController to see what is happening.

Finally, you also have the option of simply manually defining your controller service as public. Something like:

services:

    AppControllerCreateUserAccountController:
        public: true
        tags: ['controller.service_arguments'] # optional
User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement