Skip to content

[DependencyInjection] Overriding services autowired by name under _defaults bind not working #28326

Closed
@nico-incubiq

Description

@nico-incubiq

Symfony version(s) affected: 4.1.4

Description
Autowiring allows to bind certain services by name in the _defaults section, under bind in services.yaml. As follow:

services:
    _defaults:
        autowire: true
        bind:
            $isDebug: false

It is common to override base service definitions in the services_test.yaml file for example. So I would have expected to be able to override these default bind too. Like:

services:
    _defaults:
        autowire: true
        bind:
            $isDebug: true

But if you do so, then the container binding pass will throw the following exception: Unused binding "$isDebug" in service "App\Tests\Service\MySuperServiceMock"..

Possible Solution
I tracked it down and this happens because the two definitions of $isDebug are considered as distinct bindings. Consequently ResolveBindingPass::processValue() will bind the first definition, and the second one remains unbound.
The solution would be to make the second definition override the first one earlier on in the process, so there is only one binding when getting to ResolveBindingPass.

Workaround
My current workaround is to only define the binding in the main service file and make it point to a service alias; so that services_test.yaml can override that alias. As follow:

services:
    _defaults:
        autowire: true
        bind:
            $superService: '@app.service.super_service'

    app.services.super_service:
        alias: 'App/Service/SuperService'

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions