diff --git a/components/dependency_injection.rst b/components/dependency_injection.rst
index af13905456c..7dfa6ef372d 100644
--- a/components/dependency_injection.rst
+++ b/components/dependency_injection.rst
@@ -288,17 +288,21 @@ config files:
.. code-block:: php
- use Symfony\Component\DependencyInjection\Reference;
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
+ return function(ContainerConfigurator $configurator) {
+ $configurator->parameters()
+ ->set('mailer.transport', 'sendmail');
+
+ $container = $configurator->services();
+
+ $container->set('mailer', 'Mailer')
+ ->args(['%mailer.transport%']);
+
+ $container->set('newsletter_manager', 'NewsletterManager')
+ ->call('setMailer', [ref('mailer')]);
+ };
- // ...
- $container->setParameter('mailer.transport', 'sendmail');
- $container
- ->register('mailer', 'Mailer')
- ->addArgument('%mailer.transport%');
-
- $container
- ->register('newsletter_manager', 'NewsletterManager')
- ->addMethodCall('setMailer', [new Reference('mailer')]);
Learn More
----------
diff --git a/service_container.rst b/service_container.rst
index fc5405c1d7e..51ae8ea4125 100644
--- a/service_container.rst
+++ b/service_container.rst
@@ -182,19 +182,18 @@ each time you ask for it.
.. code-block:: php
// config/services.php
- use Symfony\Component\DependencyInjection\Definition;
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
- // To use as default template
- $definition = new Definition();
+ return function(ContainerConfigurator $configurator) {
+ $container = $configurator->services()
+ ->defaults()
+ ->autowire()
+ ->autoconfigure()
+ ->private();
- $definition
- ->setAutowired(true)
- ->setAutoconfigured(true)
- ->setPublic(false)
- ;
-
- // $this is a reference to the current loader
- $this->registerClasses($definition, 'App\\', '../src/*', '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}');
+ $container->load('App\\', '../src/*')
+ ->exclude('../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}');
+ };
.. tip::
@@ -396,7 +395,7 @@ pass here. No problem! In your configuration, you can explicitly set this argume
# same as before
App\:
resource: '../src/*'
- exclude: '../src/{Entity,Migrations,Tests}'
+ exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'
# explicitly configure the service
App\Updates\SiteUpdateManager:
@@ -416,6 +415,7 @@ pass here. No problem! In your configuration, you can explicitly set this argume
+
@@ -428,23 +428,23 @@ pass here. No problem! In your configuration, you can explicitly set this argume
.. code-block:: php
// config/services.php
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
use App\Updates\SiteUpdateManager;
- use Symfony\Component\DependencyInjection\Definition;
- // Same as before
- $definition = new Definition();
+ return function(ContainerConfigurator $configurator) {
+ $container = $configurator->services()
+ ->defaults()
+ ->autowire()
+ ->autoconfigure()
+ ->private();
- $definition
- ->setAutowired(true)
- ->setAutoconfigured(true)
- ->setPublic(false)
- ;
+ $container->load('App\\', '../src/*')
+ ->exclude('../src/{Entity,Migrations,Tests}');
- $this->registerClasses($definition, 'App\\', '../src/*', '../src/{Entity,Migrations,Tests}');
+ $container->set(SiteUpdateManager::class)->arg('$adminEmail', 'manager@example.com');
+ };
- // Explicitly configure the service
- $container->getDefinition(SiteUpdateManager::class)
- ->setArgument('$adminEmail', 'manager@example.com');
Thanks to this, the container will pass ``manager@example.com`` to the ``$adminEmail``
argument of ``__construct`` when creating the ``SiteUpdateManager`` service. The
@@ -503,13 +503,16 @@ parameter and in PHP config use the ``Reference`` class:
.. code-block:: php
// config/services.php
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
use App\Service\MessageGenerator;
- use Symfony\Component\DependencyInjection\Reference;
- $container->autowire(MessageGenerator::class)
- ->setAutoconfigured(true)
- ->setPublic(false)
- ->setArgument(0, new Reference('logger'));
+ return function(ContainerConfigurator $configurator) {
+ $container = $configurator->services();
+ $container->set(MessageGenerator::class)
+ ->autoconfigure()
+ ->args([ref('logger')]]);
+ };
Working with container parameters is straightforward using the container's
accessor methods for parameters::
@@ -605,13 +608,18 @@ But, you can control this and pass in a different logger:
.. code-block:: php
// config/services.php
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
use App\Service\MessageGenerator;
- use Symfony\Component\DependencyInjection\Reference;
- $container->autowire(MessageGenerator::class)
- ->setAutoconfigured(true)
- ->setPublic(false)
- ->setArgument('$logger', new Reference('monolog.logger.request'));
+ return function(ContainerConfigurator $configurator) {
+ $container = $configurator->services();
+ $container->set(SiteUpdateManager::class)
+ ->autowire()
+ ->autoconfigure()
+ ->private();
+ ->arg('$logger', ref('monolog.logger.request'));
+ };
This tells the container that the ``$logger`` argument to ``__construct`` should use
service whose id is ``monolog.logger.request``.
@@ -693,21 +701,22 @@ You can also use the ``bind`` keyword to bind specific arguments by name or type
.. code-block:: php
// config/services.php
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
use App\Controller\LuckyController;
use Psr\Log\LoggerInterface;
use Symfony\Component\DependencyInjection\Reference;
- $container->register(LuckyController::class)
- ->setPublic(true)
- ->setBindings([
- '$adminEmail' => 'manager@example.com',
- '$requestLogger' => new Reference('monolog.logger.request'),
- LoggerInterface::class => new Reference('monolog.logger.request'),
- // optionally you can define both the name and type of the argument to match
- 'string $adminEmail' => 'manager@example.com',
- LoggerInterface::class.' $requestLogger' => new Reference('monolog.logger.request'),
- ])
- ;
+ return function(ContainerConfigurator $configurator) {
+ $container = $configurator->services()->defaults()
+ ->bind('$adminEmail', 'manager@example.com')
+ ->bind('$requestLogger', ref('monolog.logger.request'))
+ ->bind(LoggerInterface::class, ref('monolog.logger.request'))
+ ->bind('string $adminEmail', 'manager@example.com')
+ ->bind(LoggerInterface::class.' $requestLogger', ref('monolog.logger.request'));
+
+ // ...
+ };
By putting the ``bind`` key under ``_defaults``, you can specify the value of *any*
argument for *any* service defined in this file! You can bind arguments by name
@@ -809,6 +818,20 @@ But, if you *do* need to make a service public, override the ``public`` setting:
+ .. code-block:: php
+
+ // config/services.php
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
+ use App\Service\MessageGenerator;
+
+ return function(ContainerConfigurator $configurator) {
+ // ... same as code before
+
+ $container->set(MessageGenerator::class)
+ ->public();
+ };
+
.. _service-psr4-loader:
Importing Many Services at once with resource
@@ -829,7 +852,7 @@ key. For example, the default Symfony configuration contains this:
# this creates a service per class whose id is the fully-qualified class name
App\:
resource: '../src/*'
- exclude: '../src/{Entity,Migrations,Tests}'
+ exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'
.. code-block:: xml
@@ -850,18 +873,14 @@ key. For example, the default Symfony configuration contains this:
.. code-block:: php
// config/services.php
- use Symfony\Component\DependencyInjection\Definition;
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
- // To use as default template
- $definition = new Definition();
-
- $definition
- ->setAutowired(true)
- ->setAutoconfigured(true)
- ->setPublic(false)
- ;
+ return function(ContainerConfigurator $configurator) {
+ // ...
- $this->registerClasses($definition, 'App\\', '../src/*', '../src/{Entity,Migrations,Tests}');
+ $container->load('App\\', '../src/*')
+ ->exclude('../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}');
+ };
.. tip::
@@ -998,27 +1017,30 @@ admin email. In this case, each needs to have a unique service id:
.. code-block:: php
// config/services.php
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
use App\Service\MessageGenerator;
use App\Updates\SiteUpdateManager;
- use Symfony\Component\DependencyInjection\Reference;
- $container->register('site_update_manager.superadmin', SiteUpdateManager::class)
- ->setAutowired(false)
- ->setArguments([
- new Reference(MessageGenerator::class),
- new Reference('mailer'),
- 'superadmin@example.com'
- ]);
-
- $container->register('site_update_manager.normal_users', SiteUpdateManager::class)
- ->setAutowired(false)
- ->setArguments([
- new Reference(MessageGenerator::class),
- new Reference('mailer'),
- 'contact@example.com'
- ]);
-
- $container->setAlias(SiteUpdateManager::class, 'site_update_manager.superadmin')
+ return function(ContainerConfigurator $configurator) {
+ // ...
+
+ $container->set('site_update_manager.superadmin', SiteUpdateManager::class)
+ ->autowire(false)
+ ->args([
+ ref(MessageGenerator::class),
+ ref('mailer'),
+ 'superadmin@example.com'
+ ]);
+ $container->set('site_update_manager.normal_users', SiteUpdateManager::class)
+ ->autowire(false)
+ ->args([
+ ref(MessageGenerator::class),
+ ref('mailer'),
+ 'contact@example.com'
+ ]);
+ $container->alias(SiteUpdateManager::class, 'site_update_manager.superadmin');
+ };
In this case, *two* services are registered: ``site_update_manager.superadmin``
and ``site_update_manager.normal_users``. Thanks to the alias, if you type-hint
diff --git a/service_container/3.3-di-changes.rst b/service_container/3.3-di-changes.rst
index b0de1d75d0d..03613a58e1e 100644
--- a/service_container/3.3-di-changes.rst
+++ b/service_container/3.3-di-changes.rst
@@ -81,9 +81,32 @@ what the file looks like in Symfony 4):
+ .. code-block:: php
+
+ // config/services.php
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
+ return function(ContainerConfigurator $configurator) {
+ $container = $configurator->services()
+ ->defaults()
+ ->autowire()
+ ->autoconfigure()
+ ->private();
+
+ $container->load('App\\', '../src/*')
+ ->exclude('../src/{Entity,Migrations,Tests}');
+
+ $container->load('App\\Controller\\', '../src/Controller')
+ ->tag('controller.service_arguments');
+ };
+
This small bit of configuration contains a paradigm shift of how services
are configured in Symfony.
+.. versionadded:: 3.4
+
+ PHP Fluent DI was introduced in Symfony 3.4.
+
.. _`service-33-changes-automatic-registration`:
1) Services are Loaded Automatically
@@ -126,6 +149,18 @@ thanks to the following config:
+ .. code-block:: php
+
+ // config/services.php
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
+ return function(ContainerConfigurator $configurator) {
+ // ...
+
+ $container->load('App\\', '../src/*')
+ ->exclude('../src/{Entity,Migrations,Tests}');
+ };
+
This means that every class in ``src/`` is *available* to be used as a
service. And thanks to the ``_defaults`` section at the top of the file, all of
these services are **autowired** and **private** (i.e. ``public: false``).
@@ -319,11 +354,15 @@ The third big change is that, in a new Symfony 3.3 project, your controllers are
.. code-block:: php
// config/services.php
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
- // ...
+ return function(ContainerConfigurator $configurator) {
+ // ...
+
+ $container->load('App\\Controller\\', '../src/Controller')
+ ->tag('controller.service_arguments');
+ };
- $definition->addTag('controller.service_arguments');
- $this->registerClasses($definition, 'App\\Controller\\', '../src/Controller/*');
But, you might not even notice this. First, your controllers *can* still extend
the same base controller class (``AbstractController``).
@@ -464,6 +503,21 @@ inherited from an abstract definition:
+ .. code-block:: php
+
+ // config/services.php
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
+ use App\Domain\LoaderInterface;
+
+ return function(ContainerConfigurator $configurator) {
+ // ...
+
+ $container->instanceof(LoaderInterface::class
+ ->public()
+ ->tag('app.domain_loader');
+ };
+
What about Performance
----------------------
diff --git a/service_container/alias_private.rst b/service_container/alias_private.rst
index c1e9da0e790..4efba8dadfa 100644
--- a/service_container/alias_private.rst
+++ b/service_container/alias_private.rst
@@ -55,10 +55,15 @@ You can also control the ``public`` option on a service-by-service basis:
.. code-block:: php
// config/services.php
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
use App\Service\Foo;
- $container->register(Foo::class)
- ->setPublic(false);
+ return function(ContainerConfigurator $configurator) {
+ $container = $configurator->services();
+ $container->set(Foo::class)
+ ->private();
+ };
.. _services-why-private:
@@ -123,12 +128,16 @@ services.
.. code-block:: php
// config/services.php
- use App\Mail\PhpMailer;
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
- $container->register(PhpMailer::class)
- ->setPublic(false);
+ use App\Mail\PhpMailer;
- $container->setAlias('app.mailer', PhpMailer::class);
+ return function(ContainerConfigurator $configurator) {
+ $container = $configurator->services();
+ $container->set(PhpMailer::class)
+ ->private();
+ $container->alias('app.mailer', PhpMailer::class);
+ };
This means that when using the container directly, you can access the
``PhpMailer`` service by asking for the ``app.mailer`` service like this::
@@ -214,7 +223,15 @@ Anonymous Services
.. note::
- Anonymous services are only supported by the XML and YAML configuration formats.
+ Anonymous services are only supported by the XML, YAML, and PHP Fluent configuration formats.
+
+.. versionadded:: 3.3
+
+ The feature to configure anonymous services in YAML was introduced in Symfony 3.3.
+
+.. versionadded:: 4.1
+
+ The feaature to configure anonymous services in PHP Fluent was introduced in Symfony 3.4.
In some cases, you may want to prevent a service being used as a dependency of
other services. This can be achieved by creating an anonymous service. These
@@ -252,6 +269,26 @@ The following example shows how to inject an anonymous service into another serv
+ .. code-block:: php
+
+ // config/services.php
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
+ use App\Foo;
+ use App\AnonymousBar;
+
+ return function(ContainerConfigurator $configurator) {
+ $container = $configurator->services();
+
+ $container->set(Foo::class)
+ ->args([inline(AnonymousBar::class)])
+ };
+
+.. note::
+
+ Anonymous services do *NOT* inherit the definitions provided from the defaults defined in the configuration. So you'll
+ need to explicitly mark service as autowired or autoconfigured when doing an anonymous service e.g.: `inline(Foo::class)->autowire()->autoconfigure()`.
+
Using an anonymous service as a factory looks like this:
.. configuration-block::
@@ -281,6 +318,21 @@ Using an anonymous service as a factory looks like this:
+ .. code-block:: php
+
+ // config/services.php
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
+ use App\Foo;
+ use App\AnonymousBar;
+
+ return function(ContainerConfigurator $configurator) {
+ $container = $configurator->services();
+
+ $container->set(Foo::class)
+ ->factory([inline(AnonymousBar::class), 'constructFoo'])
+ };
+
Deprecating Services
--------------------
@@ -313,15 +365,16 @@ or you decided not to maintain it anymore), you can deprecate its definition:
.. code-block:: php
// config/services.php
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
use App\Service\OldService;
- $container
- ->register(OldService::class)
- ->setDeprecated(
- true,
- 'The "%service_id%" service is deprecated since vendor-name/package-name 2.8 and will be removed in 3.0.'
- )
- ;
+ return function(ContainerConfigurator $configurator) {
+ $container = $configurator->services();
+
+ $container->set(OldService::class)
+ ->deprecate('The "%service_id%" service is deprecated since vendor-name/package-name 2.8 and will be removed in 3.0.');
+ };
Now, every time this service is used, a deprecation warning is triggered,
advising you to stop or to change your uses of that service.
diff --git a/service_container/autowiring.rst b/service_container/autowiring.rst
index 19ba0583ffa..bc7fa3fdbb9 100644
--- a/service_container/autowiring.rst
+++ b/service_container/autowiring.rst
@@ -104,17 +104,19 @@ both services:
.. code-block:: php
// config/services.php
- use App\Service\TwitterClient;
- use App\Util\Rot13Transformer;
+ return function(ContainerConfigurator $configurator) {
+ $container = $configurator->services()
+ ->defaults()
+ ->autowire()
+ ->autoconfigure()
+ ->private();
- // ...
+ $container->set(TwitterClient::class)
+ ->autowire(); // redundant thanks to defaults, but value is overridable on each service
+ $container->set(Rot13Transformer::class)
+ ->autowire();
+ };
- // the autowire method is new in Symfony 3.3
- // in earlier versions, use register() and then call setAutowired(true)
- $container->autowire(TwitterClient::class);
-
- $container->autowire(Rot13Transformer::class)
- ->setPublic(false);
Now, you can use the ``TwitterClient`` service immediately in a controller::
@@ -229,13 +231,19 @@ adding a service alias:
.. code-block:: php
// config/services.php
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
use App\Util\Rot13Transformer;
- // ...
+ return function(ContainerConfigurator $configurator) {
+ // ...
+
+ $container->set('app.rot13.transformer', Rot13Transformer::class)
+ ->autowire()
+ ->private();
+ $container->alias(Rot13Transformer::class, 'app.rot13.transformer');
+ };
- $container->autowire('app.rot13.transformer', Rot13Transformer::class)
- ->setPublic(false);
- $container->setAlias(Rot13Transformer::class, 'app.rot13.transformer');
This creates a service "alias", whose id is ``App\Util\Rot13Transformer``.
Thanks to this, autowiring sees this and uses it whenever the ``Rot13Transformer``
@@ -329,12 +337,18 @@ To fix that, add an :ref:`alias `:
.. code-block:: php
// config/services.php
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
use App\Util\Rot13Transformer;
use App\Util\TransformerInterface;
- // ...
- $container->autowire(Rot13Transformer::class);
- $container->setAlias(TransformerInterface::class, Rot13Transformer::class);
+ return function(ContainerConfigurator $configurator) {
+ // ...
+
+ $container->set(Rot13Transformer::class);
+ $container->alias(TransformerInterface::class, Rot13Transformer::class);
+ };
+
Thanks to the ``App\Util\TransformerInterface`` alias, the autowiring subsystem
knows that the ``App\Util\Rot13Transformer`` service should be injected when
@@ -459,24 +473,27 @@ the injection::
.. code-block:: php
// config/services.php
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
use App\Service\MastodonClient;
use App\Service\TwitterClient;
use App\Util\Rot13Transformer;
use App\Util\TransformerInterface;
use App\Util\UppercaseTransformer;
- // ...
- $container->autowire(Rot13Transformer::class);
- $container->autowire(UppercaseTransformer::class);
- $container->setAlias(TransformerInterface::class, Rot13Transformer::class);
- $container->setAlias(
- TransformerInterface::class.' $shoutyTransformer',
- UppercaseTransformer::class
- );
- $container->autowire(TwitterClient::class)
- //->setArgument('$transformer', new Reference(UppercaseTransformer::class))
- ;
- $container->autowire(MastodonClient::class);
+ return function(ContainerConfigurator $configurator) {
+ // ...
+
+ $container->set(Rot13Transformer::class)->autowire();
+ $container->set(UppercaseTransformer::class)->autowire();
+ $container->alias(TransformerInterface::class.' $shoutyTransformer', UppercaseTransformer::class);
+
+ $container->set(TwitterClient::class)
+ ->autowire()
+ // ->arg('$transformer', ref(UppercaseTransformer::class))
+
+ $container->set(MastodonClient::class)->autowire();
+ };
Thanks to the ``App\Util\TransformerInterface`` alias, any argument type-hinted
with this interface will be passed the ``App\Util\Rot13Transformer`` service.
diff --git a/service_container/calls.rst b/service_container/calls.rst
index a2dbcb7ea2d..478585a44e0 100644
--- a/service_container/calls.rst
+++ b/service_container/calls.rst
@@ -66,8 +66,13 @@ To configure the container to call the ``setLogger`` method, use the ``calls`` k
.. code-block:: php
// config/services.php
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
use App\Service\MessageGenerator;
- use Symfony\Component\DependencyInjection\Reference;
- $container->register(MessageGenerator::class)
- ->addMethodCall('setLogger', [new Reference('logger')]);
+ return function(ContainerConfigurator $configurator) {
+ // ...
+ $container->set(MessageGenerator::class)
+ ->call('setLogger', [ref('logger')]);
+ };
+
diff --git a/service_container/configurators.rst b/service_container/configurators.rst
index 29b06bdea69..aa4fdf65c31 100644
--- a/service_container/configurators.rst
+++ b/service_container/configurators.rst
@@ -166,23 +166,22 @@ all the classes are already loaded as services. All you need to do is specify th
.. code-block:: php
// config/services.php
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
+ use App\Mail\EmailConfigurator;
use App\Mail\GreetingCardManager;
use App\Mail\NewsletterManager;
- use Symfony\Component\DependencyInjection\Definition;
- use Symfony\Component\DependencyInjection\Reference;
- // Same as before
- $definition = new Definition();
+ return function(ContainerConfigurator $configurator) {
+ $container = $configurator->services();
- $definition->setAutowired(true);
+ $container->load('App\', '../src/*');
+ $container->set(NewsletterManager::class)
+ ->configurator(ref(EmailConfigurator::class), 'configure');
- $this->registerClasses($definition, 'App\\', '../src/*');
-
- $container->getDefinition(NewsletterManager::class)
- ->setConfigurator([new Reference(EmailConfigurator::class), 'configure']);
-
- $container->getDefinition(GreetingCardManager::class)
- ->setConfigurator([new Reference(EmailConfigurator::class), 'configure']);
+ $container->set(GreetingCardManager::class)
+ ->configurator(ref(EmailConfigurator::class), 'configure');
+ };
.. _configurators-invokable:
diff --git a/service_container/expression_language.rst b/service_container/expression_language.rst
index ce41f0e184c..d51d4ecbc02 100644
--- a/service_container/expression_language.rst
+++ b/service_container/expression_language.rst
@@ -53,14 +53,19 @@ to another service: ``App\Mailer``. One way to do this is with an expression:
.. code-block:: php
// config/services.php
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
use App\Mail\MailerConfiguration;
use App\Mailer;
- use Symfony\Component\ExpressionLanguage\Expression;
- $container->autowire(MailerConfiguration::class);
+ return function(ContainerConfigurator $configurator) {
+ // ...
+ $container->set(MailerConfiguration::class);
+
+ $container->set(Mailer::class)
+ ->args([expr(sprintf('service(%s).getMailerMethod()', MailerConfiguration::class))]);
+ };
- $container->autowire(Mailer::class)
- ->addArgument(new Expression('service("App\\\\Mail\\\\MailerConfiguration").getMailerMethod()'));
To learn more about the expression language syntax, see :doc:`/components/expression_language/syntax`.
@@ -102,13 +107,16 @@ via a ``container`` variable. Here's another example:
.. code-block:: php
// config/services.php
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
use App\Mailer;
- use Symfony\Component\ExpressionLanguage\Expression;
- $container->autowire(Mailer::class)
- ->addArgument(new Expression(
- "container.hasParameter('some_param') ? parameter('some_param') : 'default_value'"
- ));
+ return function(ContainerConfigurator $configurator) {
+ $container = $configurator->services();
+
+ $container->set(Mailer::class)
+ ->args([expr("container.hasParameter('some_param') ? parameter('some_param') : 'default_value'")]);
+ };
Expressions can be used in ``arguments``, ``properties``, as arguments with
``configurator`` and as arguments to ``calls`` (method calls).
diff --git a/service_container/factories.rst b/service_container/factories.rst
index 2c926bab59c..c847c4abb2b 100644
--- a/service_container/factories.rst
+++ b/service_container/factories.rst
@@ -69,13 +69,18 @@ configure the service container to use the
.. code-block:: php
// config/services.php
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
use App\Email\NewsletterManager;
use App\Email\NewsletterManagerStaticFactory;
- // ...
- $container->register(NewsletterManager::class)
- // call the static method
- ->setFactory([NewsletterManagerStaticFactory::class, 'createNewsletterManager']);
+ return function(ContainerConfigurator $configurator) {
+ $container = $configurator->services();
+
+ $container->set(NewsletterManager::class)
+ ->factory([NewsletterManagerStaticFactory::class, 'createNewsletterManager']);
+ };
+
.. note::
@@ -130,19 +135,17 @@ Configuration of the service container then looks like this:
.. code-block:: php
// config/services.php
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
use App\Email\NewsletterManager;
use App\Email\NewsletterManagerFactory;
- use Symfony\Component\DependencyInjection\Reference;
- // ...
- $container->register(NewsletterManagerFactory::class);
+ return function(ContainerConfigurator $configurator) {
+ $container = $configurator->services();
- $container->register(NewsletterManager::class)
- // call a method on the specified factory service
- ->setFactory([
- new Reference(NewsletterManagerFactory::class),
- 'createNewsletterManager',
- ]);
+ $container->set(NewsletterManager::class)
+ ->factory([ref(NewsletterManagerFactory::class), 'createNewsletterManager']);
+ };
.. _factories-invokable:
@@ -259,14 +262,16 @@ example takes the ``templating`` service as an argument:
.. code-block:: php
// config/services.php
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
use App\Email\NewsletterManager;
use App\Email\NewsletterManagerFactory;
- use Symfony\Component\DependencyInjection\Reference;
- // ...
- $container->register(NewsletterManager::class)
- ->addArgument(new Reference('templating'))
- ->setFactory([
- new Reference(NewsletterManagerFactory::class),
- 'createNewsletterManager',
- ]);
+ return function(ContainerConfigurator $configurator) {
+ $container = $configurator->services();
+
+ $container->set(NewsletterManager::class)
+ ->args([ref('templating')])
+ ->factory([ref(NewsletterManagerFactory::class), 'createNewsletterManager']);
+ };
+
diff --git a/service_container/import.rst b/service_container/import.rst
index 8dc63c800b1..3c1f82f6f69 100644
--- a/service_container/import.rst
+++ b/service_container/import.rst
@@ -117,19 +117,21 @@ a relative or absolute path to the imported file:
.. code-block:: php
// config/services.php
- use Symfony\Component\DependencyInjection\Definition;
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
- $loader->import('services/mailer.php');
+ return function(ContainerConfigurator $configurator) {
+ $configurator->import('services/mailer.php');
- $definition = new Definition();
- $definition
- ->setAutowired(true)
- ->setAutoconfigured(true)
- ->setPublic(false)
- ;
+ $container = $configurator->services()
+ ->defaults()
+ ->autowire()
+ ->autoconfigure()
+ ->private()
+ ;
- $this->registerClasses($definition, 'App\\', '../src/*',
- '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}');
+ $container->load('App\\', '../src/*')
+ ->exclude('../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}');
+ };
When loading a configuration file, Symfony loads first the imported files and
then it processes the parameters and services defined in the file. If you use the
diff --git a/service_container/injection_types.rst b/service_container/injection_types.rst
index 72faffd7a8b..2403d350b99 100644
--- a/service_container/injection_types.rst
+++ b/service_container/injection_types.rst
@@ -69,12 +69,16 @@ service container configuration:
.. code-block:: php
// config/services.php
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
use App\Mail\NewsletterManager;
- use Symfony\Component\DependencyInjection\Reference;
- // ...
- $container->register(NewsletterManager::class)
- ->addArgument(new Reference('mailer'));
+ return function(ContainerConfigurator $configurator) {
+ $container = $configurator->services();
+ $container->set(NewsletterManager::class)
+ ->args(ref('mailer'));
+ };
+
.. tip::
@@ -155,12 +159,15 @@ that accepts the dependency::
.. code-block:: php
// config/services.php
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
use App\Mail\NewsletterManager;
- use Symfony\Component\DependencyInjection\Reference;
- // ...
- $container->register('app.newsletter_manager', NewsletterManager::class)
- ->addMethodCall('setMailer', [new Reference('mailer')]);
+ return function(ContainerConfigurator $configurator) {
+ $container = $configurator->services();
+ $container->set(NewsletterManager::class)
+ ->call('setMailer', [ref('mailer')]);
+ };
This time the advantages are:
@@ -228,12 +235,15 @@ Another possibility is setting public fields of the class directly::
.. code-block:: php
// config/services.php
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
use App\Mail\NewsletterManager;
- use Symfony\Component\DependencyInjection\Reference;
- // ...
- $container->register('newsletter_manager', NewsletterManager::class)
- ->setProperty('mailer', new Reference('mailer'));
+ return function(ContainerConfigurator $configurator) {
+ $container = $configurator->services();
+ $container->set('app.newsletter_manager, NewsletterManager::class)
+ ->property('mailer', ref('mailer'));
+ };
There are mainly only disadvantages to using property injection, it is similar
to setter injection but with these additional important problems:
diff --git a/service_container/lazy_services.rst b/service_container/lazy_services.rst
index fa198777e3e..54b85da121f 100644
--- a/service_container/lazy_services.rst
+++ b/service_container/lazy_services.rst
@@ -64,10 +64,15 @@ You can mark the service as ``lazy`` by manipulating its definition:
.. code-block:: php
// config/services.php
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
use App\Twig\AppExtension;
- $container->register(AppExtension::class)
- ->setLazy(true);
+ return function(ContainerConfigurator $configurator) {
+ $container = $configurator->services();
+ $container->set(AppExtension::class)->lazy();
+ };
+
Once you inject the service into another service, a virtual `proxy`_ with the
same signature of the class representing the service should be injected. The
diff --git a/service_container/optional_dependencies.rst b/service_container/optional_dependencies.rst
index fd3fa399ec8..89de31556a0 100644
--- a/service_container/optional_dependencies.rst
+++ b/service_container/optional_dependencies.rst
@@ -34,17 +34,16 @@ if the service does not exist:
.. code-block:: php
// config/services.php
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
use App\Newsletter\NewsletterManager;
- use Symfony\Component\DependencyInjection\ContainerInterface;
- use Symfony\Component\DependencyInjection\Reference;
- // ...
+ return function(ContainerConfigurator $configurator) {
+ $container = $configurator->services();
+ $container->set(NewsletterManager::class)
+ ->args([ref('logger')->nullOnInvalid()]);
+ };
- $container->register(NewsletterManager::class)
- ->addArgument(new Reference(
- 'logger',
- ContainerInterface::NULL_ON_INVALID_REFERENCE
- ));
.. note::
@@ -91,19 +90,16 @@ call if the service exists and remove the method call if it does not:
.. code-block:: php
// config/services.php
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
use App\Newsletter\NewsletterManager;
- use Symfony\Component\DependencyInjection\ContainerInterface;
- use Symfony\Component\DependencyInjection\Reference;
-
- $container
- ->register(NewsletterManager::class)
- ->addMethodCall('setLogger', [
- new Reference(
- 'logger',
- ContainerInterface::IGNORE_ON_INVALID_REFERENCE
- ),
- ])
- ;
+
+ return function(ContainerConfigurator $configurator) {
+ $container = $configurator->services();
+ $container->set(NewsletterManager::class)
+ ->call('setLogger', [ref('logger')->ignoreOnInvalid()])
+ ;
+ };
.. note::
diff --git a/service_container/parent_services.rst b/service_container/parent_services.rst
index 9e6a3309444..806683c775b 100644
--- a/service_container/parent_services.rst
+++ b/service_container/parent_services.rst
@@ -117,28 +117,22 @@ duplicated service definitions:
.. code-block:: php
// config/services.php
- use App\Repository\BaseDoctrineRepository;
- use App\Repository\DoctrinePostRepository;
- use App\Repository\DoctrineUserRepository;
- use Symfony\Component\DependencyInjection\ChildDefinition;
- use Symfony\Component\DependencyInjection\Reference;
-
- $container->register(BaseDoctrineRepository::class)
- ->setAbstract(true)
- ->addArgument(new Reference('doctrine.orm.entity_manager'))
- ->addMethodCall('setLogger', [new Reference('logger')])
- ;
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
- // extend the App\Repository\BaseDoctrineRepository service
- $definition = new ChildDefinition(BaseDoctrineRepository::class);
- $definition->setClass(DoctrineUserRepository::class);
- $container->setDefinition(DoctrineUserRepository::class, $definition);
-
- $definition = new ChildDefinition(BaseDoctrineRepository::class);
- $definition->setClass(DoctrinePostRepository::class);
- $container->setDefinition(DoctrinePostRepository::class, $definition);
+ use App\Repository\DoctrineUserRepository;
+ use App\Repository\DoctrinePostRepository;
+ use App\Repository\BaseDoctrineRepository;
- // ...
+ return function(ContainerConfigurator $configurator) {
+ $configurator->services()
+ ->set(BaseDoctrineRepository::class) // NOTE: this must be set outside of a defaults section so that it can be extended
+ ->abstract()
+ ->args([ref('doctrine.orm.entity_manager')])
+ ->call('setLogger', [ref('logger')])
+ ->set(DoctrineUserRepository::class)->parent(BaseDoctrineRepository::class)
+ ->set(DoctrinePostRepository::class)->parent(BaseDoctrineRepository::class)
+ ;
+ };
In this context, having a ``parent`` service implies that the arguments
and method calls of the parent service should be used for the child services.
@@ -229,23 +223,23 @@ the child class:
.. code-block:: php
// config/services.php
- use App\Repository\BaseDoctrineRepository;
- use App\Repository\DoctrinePostRepository;
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
use App\Repository\DoctrineUserRepository;
- use Symfony\Component\DependencyInjection\ChildDefinition;
- use Symfony\Component\DependencyInjection\Reference;
+ use App\Repository\DoctrinePostRepository;
+ use App\Repository\BaseDoctrineRepository;
// ...
- $definition = new ChildDefinition(BaseDoctrineRepository::class);
- $definition->setClass(DoctrineUserRepository::class);
- // overrides the public setting of the parent service
- $definition->setPublic(false);
- // appends the '@app.username_checker' argument to the parent argument list
- $definition->addArgument(new Reference('app.username_checker'));
- $container->setDefinition(DoctrineUserRepository::class, $definition);
-
- $definition = new ChildDefinition(BaseDoctrineRepository::class);
- $definition->setClass(DoctrinePostRepository::class);
- // overrides the first argument
- $definition->replaceArgument(0, new Reference('doctrine.custom_entity_manager'));
- $container->setDefinition(DoctrinePostRepository::class, $definition);
+ return function(ContainerConfigurator $configurator) {
+ $configurator->services()
+ ->set(BaseDoctrineRepository::class) // NOTE: this must be set outside of a defaults section so that it can be extended
+ // ...
+ ->set(DoctrineUserRepository::class)
+ ->parent(BaseDoctrineRepository::class)
+ ->private()
+ ->arg(1, ref('app.username_checker'))
+ ->set(DoctrinePostRepository::class)
+ ->parent(BaseDoctrineRepository::class)
+ ->arg(0, ref('doctrine.custom_entity_manager'))
+ ;
+ };
diff --git a/service_container/service_decoration.rst b/service_container/service_decoration.rst
index 0904f9cb500..db90f63345f 100644
--- a/service_container/service_decoration.rst
+++ b/service_container/service_decoration.rst
@@ -39,14 +39,20 @@ When overriding an existing definition, the original service is lost:
.. code-block:: php
// config/services.php
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
use App\Mailer;
use App\NewMailer;
- $container->register(Mailer::class);
+ return function(ContainerConfigurator $configurator) {
+ $container = $configurator->services();
+
+ $container->set(Mailer::class);
- // this replaces the old App\Mailer definition with the new one, the
- // old definition is lost
- $container->register(Mailer::class, NewMailer::class);
+ // this replaces the old App\Mailer definition with the new one, the
+ // old definition is lost
+ $container->set(Mailer::class, NewMailer::class);
+ };
Most of the time, that's exactly what you want to do. But sometimes,
you might want to decorate the old one instead (i.e. apply the `Decorator pattern`_).
@@ -88,15 +94,18 @@ but keeps a reference of the old one as ``App\DecoratingMailer.inner``:
.. code-block:: php
// config/services.php
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
use App\DecoratingMailer;
use App\Mailer;
- use Symfony\Component\DependencyInjection\Reference;
- $container->register(Mailer::class);
+ return function(ContainerConfigurator $configurator) {
+ $container = $configurator->services();
- $container->register(DecoratingMailer::class)
- ->setDecoratedService(Mailer::class)
- ;
+ $container->set(Mailer::class);
+ $container->set(DecoratingMailer::class)
+ ->decorate(Mailer::class);
+ };
The ``decorates`` option tells the container that the ``App\DecoratingMailer``
service replaces the ``App\Mailer`` service. If you're using the
@@ -145,16 +154,20 @@ automatically changed to ``decorating_service_id + '.inner'``):
.. code-block:: php
// config/services.php
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
use App\DecoratingMailer;
use App\Mailer;
- use Symfony\Component\DependencyInjection\Reference;
- $container->register(Mailer::class);
+ return function(ContainerConfigurator $configurator) {
+ $container = $configurator->services();
+
+ $container->set(Mailer::class);
+ $container->set(DecoratingMailer::class)
+ ->decorate(Mailer::class)
+ ->args([ref(DecoratingMailer::class.'.inner')]);
+ };
- $container->register(DecoratingMailer::class)
- ->setDecoratedService(Mailer::class)
- ->addArgument(new Reference(DecoratingMailer::class.'.inner'))
- ;
.. tip::
@@ -206,14 +219,19 @@ automatically changed to ``decorating_service_id + '.inner'``):
.. code-block:: php
// config/services.php
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
use App\DecoratingMailer;
- use Symfony\Component\DependencyInjection\Reference;
+ use App\Mailer;
+
+ return function(ContainerConfigurator $configurator) {
+ $container = $configurator->services();
- $container->register(DecoratingMailer::class)
- ->setDecoratedService(App\Mailer, DecoratingMailer::class.'.wooz')
- ->addArgument(new Reference(DecoratingMailer::class.'.wooz'))
- // ...
- ;
+ $container->set(Mailer::class);
+ $container->set(DecoratingMailer::class)
+ ->decorate(Mailer::class, DecoratingMailer::class.'.wooz')
+ ->args([ref(DecoratingMailer::class.'.wooz')]);
+ };
Decoration Priority
-------------------
@@ -266,19 +284,24 @@ the ``decoration_priority`` option. Its value is an integer that defaults to
.. code-block:: php
// config/services.php
- use Symfony\Component\DependencyInjection\Reference;
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
+ return function(ContainerConfigurator $configurator) {
+ $container = $configurator->services();
+
+ $container->set(Foo::class);
- $container->register(Foo::class)
+ $container->set(Bar::class)
+ ->decorate(Foo::class, null, 5)
+ ->private()
+ ->args([ref(Bar::class.'.inner')]);
- $container->register(Bar::class)
- ->addArgument(new Reference(Bar::class.'.inner'))
- ->setPublic(false)
- ->setDecoratedService(Foo::class, null, 5);
+ $container->set(Baz::class)
+ ->decorate(Foo::class, null, 1)
+ ->private()
+ ->args([ref(Baz::class.'.inner')]);
+ };
- $container->register(Baz::class)
- ->addArgument(new Reference(Baz::class.'.inner'))
- ->setPublic(false)
- ->setDecoratedService(Foo::class, null, 1);
The generated code will be the following::
diff --git a/service_container/service_subscribers_locators.rst b/service_container/service_subscribers_locators.rst
index 952e61fee77..e1eb289f522 100644
--- a/service_container/service_subscribers_locators.rst
+++ b/service_container/service_subscribers_locators.rst
@@ -225,14 +225,16 @@ service type to a service.
.. code-block:: php
// config/services.php
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
use App\CommandBus;
- // ...
+ return function(ContainerConfigurator $configurator) {
+ $container = $configurator->services();
- $container
- ->register(CommandBus::class)
- ->addTag('container.service_subscriber', ['key' => 'logger', 'id' => 'monolog.logger.event'])
- ;
+ $container->set(CommandBus::class)
+ ->tag('container.service_subscriber', ['key' => 'logger', 'id' => 'monolog.logger.event']);
+ };
.. tip::
@@ -299,23 +301,24 @@ service definition to pass a collection of services to the service locator:
.. code-block:: php
// config/services.php
- use Symfony\Component\DependencyInjection\Reference;
- use Symfony\Component\DependencyInjection\ServiceLocator;
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
- // ...
+ use Symfony\Component\DependencyInjection\ServiceLocator;
- $container
- ->register('app.command_handler_locator', ServiceLocator::class)
- ->setArguments([[
- 'App\FooCommand' => new Reference('app.command_handler.foo'),
- 'App\BarCommand' => new Reference('app.command_handler.bar'),
- // if the element has no key, the ID of the original service is used
- new Reference('app.command_handler.baz'),
- )))
- // if you are not using the default service autoconfiguration,
- // add the following tag to the service definition:
- // ->addTag('container.service_locator')
- ;
+ return function(ContainerConfigurator $configurator) {
+ $container = $configurator->services();
+
+ $container->set('app.command_handler_locator', ServiceLocator::class)
+ ->args([[
+ 'App\FooCommand' => ref('app.command_handler.foo'),
+ 'App\BarCommand' => ref('app.command_handler.bar'),
+ ref('app.command_handler.baz'),
+ ]])
+ // if you are not using the default service autoconfiguration,
+ // add the following tag to the service definition:
+ // ->tag('container.service_locator');
+ ;
+ };
.. versionadded:: 4.1
@@ -364,13 +367,16 @@ Now you can use the service locator by injecting it in any other service:
.. code-block:: php
// config/services.php
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
use App\CommandBus;
- use Symfony\Component\DependencyInjection\Reference;
- $container
- ->register(CommandBus::class)
- ->setArguments([new Reference('app.command_handler_locator')])
- ;
+ return function(ContainerConfigurator $configurator) {
+ $container = $configurator->services();
+
+ $container->set(CommandBus::class)
+ ->args([ref('app.command_handler_locator')]);
+ };
In :doc:`compiler passes ` it's recommended
to use the :method:`Symfony\\Component\\DependencyInjection\\Compiler\\ServiceLocatorTagPass::register`
@@ -448,18 +454,24 @@ of the ``key`` tag attribute (as defined in the ``index_by`` locator option):
.. code-block:: php
// config/services.php
- use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
- use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
+ return function(ContainerConfigurator $configurator) {
+ $container = $configurator->services();
- $container->register(App\Handler\One::class)
- ->addTag('app.handler', ['key' => 'handler_one']);
+ $container->set(App\Handler\One::class)
+ ->tag('app.handler', ['key' => 'handler_one'])
+ ;
- $container->register(App\Handler\Two::class)
- ->addTag('app.handler', ['key' => 'handler_two']);
+ $container->set(App\Handler\Two::class)
+ ->tag('app.handler', ['key' => 'handler_two'])
+ ;
- $container->register(App\Handler\HandlerCollection::class)
- // inject all services tagged with app.handler as first argument
- ->addArgument(new ServiceLocatorArgument(new TaggedIteratorArgument('app.handler', 'key')));
+ $container->set(App\Handler\HandlerCollection::class)
+ // inject all services tagged with app.handler as first argument
+ ->args([tagged_locator('app.handler', 'key')])
+ ;
+ };
Inside this locator you can retrieve services by index using the value of the
``key`` attribute. For example, to get the ``App\Handler\Two`` service::
@@ -532,10 +544,14 @@ attribute to the locator service defining the name of this custom method:
.. code-block:: php
// config/services.php
- // ...
-
- $container->register(App\HandlerCollection::class)
- ->addArgument(new ServiceLocatorArgument(new TaggedIteratorArgument('app.handler', null, 'myOwnMethodName')));
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
+ return function(ContainerConfigurator $configurator) {
+ $configurator->services()
+ ->set(App\HandlerCollection::class)
+ ->args([service_locator(tagged('app.handler', null, 'myOwnMethodName'))])
+ ;
+ };
Service Subscriber Trait
------------------------
diff --git a/service_container/shared.rst b/service_container/shared.rst
index 00f0ddf0e43..42e1c1e877d 100644
--- a/service_container/shared.rst
+++ b/service_container/shared.rst
@@ -32,10 +32,16 @@ in your service definition:
.. code-block:: php
// config/services.php
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
use App\SomeNonSharedService;
- $container->register(SomeNonSharedService::class)
- ->setShared(false);
+ return function(ContainerConfigurator $configurator) {
+ $container = $configurator->services();
+
+ $container->set(SomeNonSharedService::class)
+ ->share(false);
+ };
Now, whenever you request the ``App\SomeNonSharedService`` from the container,
you will be passed a new instance.
diff --git a/service_container/synthetic_services.rst b/service_container/synthetic_services.rst
index ad4cc9924ff..30c626b59f5 100644
--- a/service_container/synthetic_services.rst
+++ b/service_container/synthetic_services.rst
@@ -64,10 +64,14 @@ configuration:
.. code-block:: php
// config/services.php
- // synthetic services don't specify a class
- $container->register('app.synthetic_service')
- ->setSynthetic(true)
- ;
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
+ return function(ContainerConfigurator $configurator) {
+ $container = $configurator->services();
+ $container->set('app.synthetic_service')
+ ->synthetic();
+ };
+
Now, you can inject the instance in the container using
:method:`Container::set() `::
diff --git a/service_container/tags.rst b/service_container/tags.rst
index 9a98cf17619..187d50a52e9 100644
--- a/service_container/tags.rst
+++ b/service_container/tags.rst
@@ -38,11 +38,17 @@ example:
.. code-block:: php
// config/services.php
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
use App\Twig\AppExtension;
- $container->register(AppExtension::class)
- ->setPublic(false)
- ->addTag('twig.extension');
+ return function(ContainerConfigurator $configurator) {
+ $container = $configurator->services();
+ $container->set(AppExtension::class)
+ ->private()
+ ->tag('twig.extension');
+ };
+
Services tagged with the ``twig.extension`` tag are collected during the
initialization of TwigBundle and added to Twig as extensions.
@@ -96,13 +102,17 @@ If you want to apply tags automatically for your own services, use the
.. code-block:: php
// config/services.php
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
use App\Security\CustomInterface;
- // ...
- // services whose classes are instances of CustomInterface will be tagged automatically
- $container->registerForAutoconfiguration(CustomInterface::class)
- ->addTag('app.custom_tag')
- ->setAutowired(true);
+ return function(ContainerConfigurator $configurator) {
+ $container = $configurator->services();
+ $container->instanceof(CustomInterface::class)
+ ->autowire()
+ ->tag('app.custom_tag');
+ };
+
For more advanced needs, you can define the automatic tags using the
:method:`Symfony\\Component\\DependencyInjection\\ContainerBuilder::registerForAutoconfiguration`
@@ -182,9 +192,15 @@ Then, define the chain as a service:
.. code-block:: php
// config/services.php
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
use App\Mail\TransportChain;
- $container->autowire(TransportChain::class);
+ return function(ContainerConfigurator $configurator) {
+ $container = $configurator->services();
+ $container->set(TransportChain::class);
+ };
+
Define Services with a Custom Tag
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -231,12 +247,17 @@ For example, you may add the following transports as services:
.. code-block:: php
// config/services.php
- $container->register(\Swift_SmtpTransport::class)
- ->addArgument('%mailer_host%')
- ->addTag('app.mail_transport');
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
+ return function(ContainerConfigurator $configurator) {
+ $container = $configurator->services();
+ $container->set(\Swift_SmtpTransport::class)
+ ->args(['%mailer_host%'])
+ ->tag('app.mail_transport');
- $container->register(\Swift_SendmailTransport::class)
- ->addTag('app.mail_transport');
+ $container->set(\Swift_SendmailTransport::class)
+ ->tag('app.mail_transport');
+ };
Notice that each service was given a tag named ``app.mail_transport``. This is
the custom tag that you'll use in your compiler pass. The compiler pass is what
@@ -387,12 +408,17 @@ To answer this, change the service declaration:
.. code-block:: php
// config/services.php
- $container->register(\Swift_SmtpTransport::class)
- ->addArgument('%mailer_host%')
- ->addTag('app.mail_transport', ['alias' => 'smtp']);
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
- $container->register(\Swift_SendmailTransport::class)
- ->addTag('app.mail_transport', ['alias' => 'sendmail']);
+ return function(ContainerConfigurator $configurator) {
+ $container = $configurator->services();
+ $container->set(\Swift_SmtpTransport::class)
+ ->args(['%mailer_host%'])
+ ->tag('app.mail_transport', ['alias' => 'smtp']);
+
+ $container->set(\Swift_SendmailTransport::class)
+ ->tag('app.mail_transport', ['alias' => 'sendmail']);
+ };
.. tip::
@@ -500,17 +526,20 @@ first constructor argument to the ``App\HandlerCollection`` service:
.. code-block:: php
// config/services.php
- use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
- $container->register(App\Handler\One::class)
- ->addTag('app.handler');
+ return function(ContainerConfigurator $configurator) {
+ $container = $configurator->services();
+ $container->set(App\Handler\One::class)
+ ->tag('app.handler');
- $container->register(App\Handler\Two::class)
- ->addTag('app.handler');
+ $container->set(App\Handler\Two::class)
+ ->tag('app.handler');
- $container->register(App\HandlerCollection::class)
- // inject all services tagged with app.handler as first argument
- ->addArgument(new TaggedIteratorArgument('app.handler'));
+ $container->set(App\HandlerCollection::class)
+ // inject all services tagged with app.handler as first argument
+ ->args([tagged('app.handler')]);
+ };
After compilation the ``HandlerCollection`` service is able to iterate over your
application handlers::
@@ -558,7 +587,12 @@ application handlers::
.. code-block:: php
// config/services.php
- $container->register(App\Handler\One::class)
- ->addTag('app.handler', ['priority' => 20]);
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
+ return function(ContainerConfigurator $configurator) {
+ $container = $configurator->services();
+ $container->set(App\Handler\One::class)
+ ->tag('app.handler', ['priority' => 20]);
+ };
Note that any other custom attributes will be ignored by this feature.