Brian Brownton
Brian Brownton

Reputation: 1331

Symfony4: inject service into controller __construct (constructor)

I am having trouble accessing an injected service in the constructor of one of my controllers.

Per http://symfony.com/doc/current/service_container/injection_types.html I believe I have done the injection correctly, however when I try to load a view from the controller, I get the following error:

Argument 1 passed to Regions\AnalyticsBundle\Controller\PatternsController::__construct()
must be an instance of Regions\AnalyticsBundle\Controller\PatternCacheService, instance of
Regions\AnalyticsBundle\Service\PatternCacheService given, called
in /var/tmp/symfony/cache/dev/ContainerLoHUcSH/getPatternsControllerService.php on line 9

It seems like the error indicates that the type hinting in the constructor is trying making it look for an instance in the *\Controller\* namespace instead of the *\Services\* namespace - what am I doing wrong or not seeing here?

Details of my setup are as follows...

Symfony 4.1.0, PHP 7.2.5

services.yaml

services:
    ...

    pattern_cache_service:
        class: Regions\AnalyticsBundle\Service\PatternCacheService
        public: true

    Regions\AnalyticsBundle\Controller\PatternsController:
        arguments: ['@pattern_cache_service']

Controller:

namespace Regions\AnalyticsBundle\Controller;

class PatternsController extends BaseController
{

    private $pcs;

    public function __construct(PatternCacheService $pcs)
    {
        $this->pcs = $pcs;
    }
}

Upvotes: 1

Views: 10144

Answers (3)

BentCoder
BentCoder

Reputation: 12740

  1. You don't need a service definition for pattern_cache_service. It should autowire your service if autowire: true is set.
  2. PatternCacheService should be private as you don't want to access it from within container. Suggested practise!
  3. You don't need a service definition for PatternsController either.

Note: You should not use "bundles" anymore in Symfony 4 so I would get rid of AnalyticsBundle.

Note: Better organise your configuration files as show here: Organising route, service and parameter configuration files in symfony 4 applications.

This should suffice:

services.yaml

services:
    _defaults:
        autowire: true
        autoconfigure: true
        public: false

    App\:
        resource: '../src/*'
        exclude: '../src/{Entity,....so on .....,Kernel.php}'

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

PatternsController

namespace Regions\AnalyticsBundle\Controller;

use Regions\AnalyticsBundle\Service\PatternCacheService;

class PatternsController
{
    private $pcs;

    public function __construct(PatternCacheService $pcs)
    {
        $this->pcs = $pcs;
    }
}

Upvotes: 2

β.εηοιτ.βε
β.εηοιτ.βε

Reputation: 39129

You forgot a use in your Controller, making PHP think that your service is in the same namespace as your controller.

<?php

namespace Regions\AnalyticsBundle\Controller;

use Regions\AnalyticsBundle\Service\PatternCacheService;

class PatternsController extends BaseController
{

    private $pcs;

    public function __construct(PatternCacheService $pcs)
    {
        $this->pcs = $pcs;
    }
}

This was actually raised as part of your error message

Argument 1 passed to Regions\AnalyticsBundle\Controller\PatternsController::__construct() must be an instance of Regions\AnalyticsBundle\Controller\PatternCacheService

When what you expected was your controller to need an instance of Regions\AnalyticsBundle\Service\PatternCacheService

Upvotes: 2

localheinz
localheinz

Reputation: 9582

The class PatternCacheService cannot be found in the namespace Regions\AnalyticsBundle\Controller.

Add an import:

<?php

namespace Regions\AnalyticsBundle\Controller;

use Regions\AnalyticsBundle\Service\PatternCacheService;

class PatternsController extends BaseController
{

    private $pcs;

    public function __construct(PatternCacheService $pcs)
    {
        $this->pcs = $pcs;
    }
}

For reference, see

Upvotes: 2

Related Questions