1

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?

7
  • I don't see the problem. You would just define your foo service and inject the desired dependency. If you want to use autowiring then you would be using class names for your services. In this case, it would be easy enough to create a WorkerUploaderPath which extends from UploaderPath. Commented Jun 13, 2020 at 12:31
  • It's also possible that you may want to using the binding capability of autowire. Commented Jun 13, 2020 at 12:36
  • I think @Cerad missed that you are trying to inject into a function. This is possible in Controllers that extend AbstractController but not possible in general services. In that case, you would need to inject your $workerUploader in the class constructor, set it as a class property and then use it like $this->workerUploader->doFoo() Commented Jun 13, 2020 at 14:38
  • @craigh I thought about that but only after posting my original comments. It is possible that foo is actually a controller action method. Was hoping to get a bit of feedback from the poster as it is not clear to me exactly what they are trying to do. Commented Jun 13, 2020 at 14:43
  • @craigh but then I have to register the controller in services.yaml and pass it as an argument eg: @worker_uploader? Commented Jun 13, 2020 at 18:35

1 Answer 1

2

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

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

2 Comments

You made me the day. Still valid in SF6. I'm working with multiple DBAL connections and I did not want to manually attach the proper connection in the services.yaml for each of the many controllers. Instead of injecting Connection $connection I now use things like Connection $connectionProductionIreland and Connection $connectionProductionFrankfurt and it just works. The controller demands what connection it wants and it gets injected!
Although as stated here symfonycasts.com/screencast/symfony-fundamentals/global-bind towards the end, the new #[Autowire()] attribute liberates us even from declaring the globals. In our case if the services are called db.ireland and db.frankfurt one can do: public function __invoke( #[Autowire( service: 'db.ireland )] Connection $ireland, #[Autowire( service: 'db.frankfurt )] Connection $frankfurt ) and all is autocontained in the consuming class. No need to edit the services.yaml at all for routing the services.

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.