New in Symfony 3.3: Simpler service configuration

In Symfony 3.3, we added new features to simplify the services configuration. This will make your applications easier to maintain and it will improve your development productivity.

Short syntax for service configuration

Contributed by
Maxime Steinhausser
in #21313.

In Symfony 3.3, the class argument is optional for unnamed services. When services are defined using YAML format, we decided to go a step further and optimize the usual case where a service only contains the class and arguments options:

1
2
3
4
5
6
7
8
# Before
services:
    App\Foo\Bar:
        arguments: ['@baz', 'foo', '%qux%']

# After
services:
    App\Foo\Bar: ['@baz', 'foo', '%qux%']

Default service configuration

One of the ideas proposed for the upcoming Symfony 4.0 was to make services private by default. We discarded the idea because of the pain that it would have introduced when upgrading Symfony 3.x applications. However, we decided to add a feature to simplify defining default service configurations.

The new services._defaults option lets you set the value of the public, tags and autowire options for all the services defined in a single file:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
services:
    # these options are applied to all services defined in this file
    _defaults:
        public: false
        autowire: true

    foo_bar:
        class: App\Foo\Bar

    foo:
        class: App\Foo
        # each service can override the default options set in the file
        public: true

Interface-based service configuration

Contributed by
Nicolas Grekas and Kévin Dunglas
in #21530.

Once the _defaults option was added, we decided to extend the idea to set default configuration values depending on the class interface using a new option called _instanceof. This way you can for example add the twig.extension to every service that uses Twig_ExtensionInterface:

1
2
3
4
5
# app/config/services.yml
services:
    _instanceof:
        Twig_ExtensionInterface:
            tags: ['twig.extension']

Combining default and interface-based configuration

If you combine the default and interface-based configuration with the recently added glob support, the service configuration of your application can be as concise as:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
# config/services.yml
services:
    _defaults:
        autowire: true
        public: false

    _instanceof:
        # Add the console.command tag to all services defined in this file having this type
        Symfony\Component\Console\Command\Command:
            tags: ['console.command']
            public: true # needed because commands must be public

        Twig_ExtensionInterface:
            tags: ['twig.extension']

        Symfony\Component\EventDispatcher\EventSubscriberInterface:
            tags: ['kernel.event_subscriber']

    # Register all classes in these directories as services
    App\:
        resource: ../src/{Action,Command,EventSubscriber,Twig}

Comments

All those features are only available in YAML format?
@Fabien all are available for YAML and XML ... except for the first one about short syntax.
Hi!

Nice work! the "_instanceof" feature is a good idea!

There is a "max level deep" to find interfaces? Maybe a little magic when this feature is triggered by a very deep implemented interface. May cause some troubles to find the cause.

Best regards,
Romain
yeah ! good idea/work ;) thx
Could I for example add some custom function to all entity repositories using `_instanceof` right? or it will only work for those services in the same configuration file? Can I use it global?
Great feature, thx !
Can't wait for the release :)

Do they inherit? Like having a services.yml loading other ymls but the service.yml has some ` _instanceof` configs.
I hope not ^^
Oh, really convenient! Thanks... Symfony 3.3 !!
Wouldn't the default values for services allow to still make services private by default? Then upgrading from Symfony 3.x would be as easy as set the default to true. Alternatively the public flag could also be added to the services requiring it.
Awesome feature! It's convenient and also, it encourages a little more to organize our services declarations into dedicated files. The end of the looooong services.yml files is coming!
Really easy!!!

I can't wait for 3.3 release!
Awesome feature (:

Comments are closed.

To ensure that comments stay relevant, they are closed for old posts.