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
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
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}
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 (: