New in Symfony 3.3: Optional class for named services
January 9, 2017 • Published by Javier Eguiluz
Warning: This post is about an unsupported Symfony version. Some of this information may be out of date. Read the most recent Symfony Docs.
Contributed by
Martin Hasoň
and Nicolas Grekas
in #21133.
Services in Symfony applications are traditionally defined in YAML, XML or PHP configuration files. A typical but simple service definition looks like this in YAML:
1 2 3 4 5
# app/config/services.yml
services:
app.mailer:
class: AppBundle\Mailer
arguments: [sendmail]
And like this in XML:
1 2 3 4 5 6 7 8 9 10 11 12 13
<!-- app/config/services.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services
http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="app.mailer" class="AppBundle\Mailer">
<argument>sendmail</argument>
</service>
</services>
</container>
In Symfony 3.3, we're adding some new features to the Dependency Injection component
that allow working with services in a different manner. For that reason, in
Symfony 3.3, the class
argument of the services is now optional. When it's
undefined, Symfony considers that the id
of the service is the PHP class:
1 2 3 4 5 6 7 8 9 10
services:
# ...
# traditional service definition
app.manager.user:
class: AppBundle\EventListener\UserManager
tags: ['kernel.event_subscriber']
# new service definition allowed in Symfony 3.3
AppBundle\EventListener\UserManager:
tags: ['kernel.event_subscriber']
When using this new feature, getting services from the container requires to pass the full PHP namespace:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
use AppBundle\EventListener\UserManager;
// ...
public function editAction()
{
// ...
// before Symfony 3.3
$this->get('app.manager.user')->save($user);
// Symfony 3.3
$this->get(UserManager::class)->save($user);
// ...
}
The traditional service definition will keep working as always (and it's even mandatory to use it in cases like decorating services). However, this new feature together with other optional features such as autowiring and defining default service options per file, will enable RAD ("rapid application development") for those projects and developers that need it:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
services:
# default options applied to all the services in this file
_defaults:
# enable autowiring for these services
autowire: true
# make services private by default
public: false
App\TwigExtension:
tags: [twig.extension]
App\Doc:
tags:
- { name: twig.runtime, id: "App\\TwigExtension" }
Help the Symfony project!
As with any Open-Source project, contributing code or documentation is the most common way to help, but we also have a wide range of sponsoring opportunities.
Comments are closed.
To ensure that comments stay relevant, they are closed for old posts.
You put an example of the new service definition in Yaml but not in Xml, maybe you could add it to show people it works too :)
I'm pretty sure we will have fun with the additional \ to not forget when using class name as id in Service tags properties..
+1: missing example with XML.
Can anyone please tell me what do we gain with this?
Of course, this is my opinion, but don't let Symfony fall in the easy way of doing everything RAD, and focus on DX, improve your code in order to make it accessible for more people and give the community the tools to make this important RAD part of the ecosystem, not part of the core :)
Thanks for the Response, Fabien.
-1