symfony: Importing configuration from other yaml file to config/services.yaml doesn't work

Q A
Bug report? yes
Feature request? no
BC Break report? no
RFC? no
Symfony version 4.0.4

Importing configuration from other yaml file to config/services.yaml doesn’t work well. I made simple reproducer codebase here. Maybe seeing commit logs helps you to understand about my reporting. Thanks.

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 18 (9 by maintainers)

Most upvoted comments

Just put your .yaml file in the dir config/services, and add to src/Kernel.php, at the end of the configureContainer method:

$loader->load($confDir.'/services/*'.self::CONFIG_EXTS, 'glob');

This feels a bit counter-intuitive behavior to me as we are used to expect more specific definitions to override more generic ones. While the roots of the issue are quite clear once you spent some time to grasp it then the vague suggestion in documentation and few issues on github (this included) suggest more explicit filtering in the global auto-wiring definition in services.yaml and this looks a bit tedious and error prone process.

Is it possible to call it a documentation bug instead and opt in for documenting the following (or similar) approach (or rather a suggestion) in the dedicated doc page (How to Import Configuration Files/Resources):

Once you decide to split into multiple service definition files one just needs to extract the golbal auto-wiring definition as well and just beware to import it first. E.g.

# config/services/default_autowire.yaml
services:
    # default configuration for services in *this* file
    _defaults:
        autowire: true      # Automatically injects dependencies in your services.
        autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.

    # makes classes in src/ available to be used as services
    # this creates a service per class whose id is the fully-qualified class name
    App\:
        resource: '../../src/*'
        exclude: '../../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'

    # controllers are imported separately to make sure services can be injected
    # as action arguments even if you don't extend any base controller class
    App\Controller\:
        resource: '../../src/Controller'
        tags: ['controller.service_arguments']

and then


# config/service.yaml

# This file is the entry point to configure your own services.
# Files in the packages/ subdirectory configure your dependencies.
imports:
    - { resource: services/default_autowire.yaml }
    - { resource: services/something.yaml }
    - { resource: services/other_thing.yaml }

parameters:
    # anything you decided not to split and with highest precedence

services:
    # default configuration for services in *this* file
    _defaults:
        autowire: true      # Automatically injects dependencies in your services.
        autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.

    # anything else you decided not to split and with highest precedence

IMO even if only a soft suggestion it will immediately rise awareness of what is going on. Alternative example with filtering out services could also be provided for verbosity.

I could try to provide a PR for the docs if it looks like something less confusing and “nice to have”? CC @xabbuh

I noticed some weird Symfony behaviour during import. When services are defined in config/services.yaml file, they are loading properly, but when I configure them in config/services/services.yaml, they start to give error like

Cannot autowire service “App\Command***\XyzCommand”: argument “$env” of method “__construct()” is type-hinted “string”, you should configure its
value explicitly.

what about bind: ?

it won’t work if you move the argument $my_argument to anthor separated services file (e.g services/something.yaml) and rather it throws this weired exception:

A binding is configured for an argument named "$my_argument" under "_defaults" in file
 "/path/to/config/services/something.yaml",
 but no corresponding argument has been found. It may be unused and should be removed, or it may have a typo.

if each services file has its own bind: section, does this lead to conflict/overrids ? how to counter this properly ?

If you want this to work IMHO, is to remove the _defaults from the services.yaml and add it in the sample.yaml.

This is what i’m doing.

I can’t tell if it’s really a bug or a missusage.

Status: Needs Review