Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 56 additions & 12 deletions service_container/service_decoration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -62,16 +62,66 @@ that you can reference it:
App\Mailer: ~

App\DecoratingMailer:
# overrides the App\Mailer service
# but that service is still available as App\Mailer.inner
decorates: App\Mailer

.. code-block:: xml

<!-- config/services.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsd="http://www.w3.org/2001/XMLSchema-instance"
xsd:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">

<services>
<service id="App\Mailer" />

<service id="App\DecoratingMailer"
decorates="App\Mailer"
/>

</services>
</container>

.. code-block:: php

// config/services.php
use App\DecoratingMailer;
use App\Mailer;
use Symfony\Component\DependencyInjection\Reference;

$container->register(Mailer::class);

$container->register(DecoratingMailer::class)
->setDecoratedService(Mailer::class)
;

The ``decorates`` option tells the container that the ``App\DecoratingMailer``
service replaces the ``App\Mailer`` service. If you're using the
:ref:`default services.yaml configuration <service-container-services-load-example>`,
the decorated service is automatically injected into the decorating service
constructor. The name of the argument is ``decorating_service_id + '.inner'``
(in this example, ``App\DecoratingMailer.inner``).

.. versionadded:: 4.1
The autowiring of the decorated service was introduced in Symfony 4.1.

If you are not using autowiring or the decorating service has more than one
constructor argument of the type of the decorated service, you must inject the
decorated service explicitly:

.. configuration-block::

.. code-block:: yaml

# config/services.yaml
services:
App\Mailer: ~

App\DecoratingMailer:
decorates: App\Mailer
# pass the old service as an argument
arguments: ['@App\DecoratingMailer.inner']

# private, because usually you do not need to fetch App\DecoratingMailer directly
public: false

.. code-block:: xml

<!-- config/services.xml -->
Expand All @@ -85,7 +135,6 @@ that you can reference it:

<service id="App\DecoratingMailer"
decorates="App\Mailer"
public="false"
>
<argument type="service" id="App\DecoratingMailer.inner" />
</service>
Expand All @@ -105,16 +154,11 @@ that you can reference it:
$container->register(DecoratingMailer::class)
->setDecoratedService(Mailer::class)
->addArgument(new Reference(DecoratingMailer::class.'.inner'))
->setPublic(false)
;

The ``decorates`` option tells the container that the ``App\DecoratingMailer`` service
replaces the ``App\Mailer`` service. The old ``App\Mailer`` service is renamed to
``App\DecoratingMailer.inner`` so you can inject it into your new service.

.. tip::

The visibility (public) of the decorated ``App\Mailer`` service (which is an alias
The visibility of the decorated ``App\Mailer`` service (which is an alias
for the new service) will still be the same as the original ``App\Mailer``
visibility.

Expand Down