Home > Enterprise >  Service injection fails only on certain function of the same class
Service injection fails only on certain function of the same class

Time:08-27

Moving from symfony 3 to 4 I started injecting the service according to this.

Most functions where I inject the "helper" service it works fine, but for some reason it fails on a few of them and I can't figure out what I've done differently... Here's the error:

Could not resolve argument $helper of "App\Controller\Poslog\OperatorController::historyindividualaction()", maybe you forgot to register the controller as a service or missed tagging it with the "controller.service_arguments"?

I've omitted the contents if the functions completely as it doesn't matter what they contain, I can comment out the entire code inside the HistoryIndividualAction() and still get the exact same error message.

The OperatorController::newAction() below works perfectly fine (as well as a number of other functions within the same object), while the OperatorController::HistoryIndividualAction() fails.

use App\Service\globalHelper as globalHelper;
...
class OperatorController extends AbstractController
{

  public function newAction(Request $request, ACRGroup $ACRGroup = null, globalHelper $helper)
  {
  ...
  }

  public function HistoryIndividualAction($operatorId, globalHelper $helper)
  {
  ...
  }
}

The routing looks like this

operator_new:
    path:     /new/{ACRGroup}
    defaults: { _controller: App\Controller\Poslog\OperatorController::newAction, ACRGroup: null }
    methods:  [GET, POST]

operator_history_individual:
    path:     /history/individual/{operatorId}
    defaults: { _controller: App\Controller\Poslog\OperatorController::historyIndividualAction }
    methods:  GET

Services.yml

# This file is the entry point to configure your own services.
# Files in the packages/ subdirectory configure your dependencies.

# Put parameters here that don't need to change on each machine where the app is deployed
# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
parameters:
    locale: en


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'

    # controllers are imported separately to make sure services can be injected
    # as action arguments even if you don't extend any base controller class
    App\Controller\:
        resource: '../src/Controller/'
        tags: ['controller.service_arguments']


    # add more service definitions when explicit configuration is needed
    # please note that last definitions always *replace* previous ones

    globalHelper:
        class: App\Service\globalHelper
        public: false
        arguments: ['@service_container', '@doctrine.orm.entity_manager']

GlobalHelper starts out like this:

namespace App\Service;

use Symfony\Component\DependencyInjection\ContainerInterface as Container;
//use Doctrine\ORM\EntityManager as EntityManager; //gave deprecation notice, profiler suggested to change to below and the deprecation notice disappeared.
use Doctrine\ORM\EntityManagerInterface as EntityManager;


class globalHelper {

    private $container;
    private $em;

    public function __construct(Container $container, EntityManager $em) {
        $this->container = $container;
        $this->em = $em;
    }

CodePudding user response:

The basic problem is that method names are case sensitive and you had a mismatch.

  // Change
  public function HistoryIndividualAction(
  // To
  public function historyIndividualAction(

Normally I would just have called this a typo and moved on but the error is interesting. I would have expected perhaps an unknown method sort of message but Symfony would have dealt with that. The error comes from trying to process the method's arguments.

There is a huge sub-system behind Symfony's ability to inject action arguments. Not as simple as it may look and it involves caching information about the action signatures using the method name. And that is where the case mismatch becomes significant.

So I think it might be worth keeping this answer around just for developers who might encounter a similar error message.

CodePudding user response:

Try sorting your arguments differently in your controller action.

public function newAction(Request $request, ACRGroup, globalHelper $helper, $ACRGroup = null) {
    // ...
}

And try to clear the cache:

php bin/console cache:clear
  • Related