Search code examples
symfonysymfony4

How to inject service by name in symfony when using DependencyInjection


I have one service which is defined in services.yaml with different parameters:

user_uploader:
    class: App\Services\UploaderPath
    arguments:
        $basePath: "%users_directory%"

worker_uploader:
    class: App\Services\UploaderPath
    arguments:
        $basePath: "%workers_directory%"

When I'm injecting that service to another service everything is fine because I can inject it via name. The problem occurrs when I want to use DI and use for example worker_uploader

public function foo(UploaderPath $workerUploader) {
}

How in this case inject proper service?


Solution

  • If you are using Symfony 3.4 or higher you can leverage bind in order to do that.

    In service yaml

    services:
        _defaults:
            bind:
                $userUploader: '@user_uploader'
                $workerUploader: '@worker_uploader'
    
        user_uploader:
            class: App\Services\UploaderPath
                arguments:
                    $basePath: "%users_directory%"
    
        worker_uploader:
            class: App\Services\UploaderPath
                arguments:
                    $basePath: "%workers_directory%"
    

    Then let's say in a SomeController you can use it like so:

    class SomeController extends AbstractController
    {
        private $userUploader;
        private $workerUploader;
    
        public function __construct($userUploader, $workerUploader)
        {
            $this->userUploader = $userUploader;
            $this->workerUploader = $workerUploader;
        }
    }
    

    More details here https://symfony.com/doc/4.4/service_container.html#binding-arguments-by-name-or-type