0

I'm looking for a concrete example of implementing DI with Symfony controllers... https://symfony.com/doc/3.4/controller/service.html hasn't been much help.

Config

search_service:
    class:        Acme\MyBundle\Services\SearchService

search_controller:
    class:        Acme\MyBundle\Controller\SearchController
    arguments:    ['@search_service']

Controller

// Acme/MyBundle/Controllers/SearchController.php

class SearchController extends Controller
{
    public function __construct(SearchService $searchService)
    {
        $this->searchService = $searchService;
    }
}

Gives me:

Type error: Argument 1 passed to Acme\\MyBundle\\Controller\\SearchController::__construct() must be an instance of Acme\\MyBundle\\Services\\SearchService, none given

Any help appreciated :)

2 Answers 2

1

Your controller does not work, because you don't have a namespace. So at the start, add correct namespace, but it will still be problematic to inject parameters with manual wiring, because you extend base controller.

Better just use autowiring, with that you won't need to define your dependencies from services.yml and it will work with controllers easily.

Here's example

  # app/config/services.yml
services:
    # default configuration for services in *this* file
    _defaults:
        # automatically injects dependencies in your services
        autowire: true
        # automatically registers your services as commands, event subscribers, etc.
        autoconfigure: true
        # this means you cannot fetch services directly from the container via $container->get()
        # if you need to do this, you can override this setting on individual services
        public: false

    # makes classes in src/AppBundle available to be used as services
    # this creates a service per class whose id is the fully-qualified class name
    AppBundle\:
        resource: '../../src/AppBundle/*'
        # you can exclude directories or files
        # but if a service is unused, it's removed anyway
        exclude: '../../src/AppBundle/{Entity,Repository}'

    # controllers are imported separately to make sure they're public
    # and have a tag that allows actions to type-hint services
    AppBundle\Controller\:
        resource: '../../src/AppBundle/Controller'
        tags: ['controller.service_arguments']

ps. Also, I recommend to don't extend base controller at all, because in that way you get too much dependencies you actually don't need. Better to get twig, services and everything you need by wiring them.

Sign up to request clarification or add additional context in comments.

5 Comments

Tried this, but seem to be having issues resolving paths... ../src/Controller where's the namespace and bundle in that path?
@cloakedninjas Updated code for version below 4, try now, but i'm not sure why you have this "Acme prefix" before :D, is that demo app ? Do you have dir structure like /src/AppBundle ? Please add autoload section of composer.json
It's not Acme - but the name of our company, we have several namespaces in our repo Company1\CoolBundle, Company2\AwesomeBundle
However - it's still unable to find these paths The file "../../src/MyBundle/Controller" does not exist (in: /srv/www/src/Acme/MyBundle/DependencyInjection/../Resources/config).
@cloakedninjas It will work, when you add cottect bundle name
0

I had to make the follow changes to get it working for my 3.4 installation:

Change resource relative path

Acme\MyBundle\Controller\:
    resource: '../../Controller'
    tags: ['controller.service_arguments']

Change 'name' of the controller to the full classname

Acme\MyBundle\Controller\SearchController:
    class:        Acme\MyBundle\Controller\SearchController
    arguments:    ['@search_service']

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.