Skip to content
Open
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
146 changes: 87 additions & 59 deletions service_container/service_decoration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -211,84 +211,112 @@ automatically changed to ``'.inner'``):
->args([service('.inner')]);
};

.. deprecated:: 6.3
When decorating a service, the original service (e.g. ``App\Mailer``) is available
inside the decorating service (e.g. ``App\DecoratingMailer``) using an ID constructed
as "Decorating service ID" + the ``.inner`` suffix (e.g. in the previous example,
the ID is ``'App\DecoratingMailer.inner'``). You can control the inner service
name via the ``decoration_inner_name`` option:

The ``#[MapDecorated]`` attribute is deprecated since Symfony 6.3.
Instead, use the
:class:`#[AutowireDecorated] <Symfony\\Component\\DependencyInjection\\Attribute\\AutowireDecorated>` attribute.
.. configuration-block::

.. note::
.. code-block:: php-attributes

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.
// when using the #[AutowireDecorated] attribute, you can name the argument
// that holds the decorated service however you like, without needing to
// configure that name explicitly
#[AutowireDecorated] private Mailer $originalMailer,

.. note::
.. code-block:: yaml

All custom :doc:`service tags </service_container/tags>` from the decorated
service are removed in the new service. Only certain built-in service tags
defined by Symfony are retained: ``container.service_locator``, ``container.service_subscriber``,
``kernel.event_subscriber``, ``kernel.event_listener``, ``kernel.locale_aware``,
and ``kernel.reset``.
# config/services.yaml
services:
App\DecoratingMailer:
# ...
decoration_inner_name: 'original_mailer'
arguments: ['@original_mailer']

.. note::
# if you decorate a lot of services, consider adding the full
# original service ID as part of the new ID
decoration_inner_name: 'App\Mailer.original'
arguments: ['@App\Mailer.original']

The generated inner id is based on the id of the decorator service
(``App\DecoratingMailer`` here), not of the decorated service (``App\Mailer``
here). You can control the inner service name via the ``decoration_inner_name``
option:
.. code-block:: xml

.. configuration-block::
<!-- 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 https://symfony.com/schema/dic/services/services-1.0.xsd">

.. code-block:: yaml
<services>
<!-- ... -->

# config/services.yaml
services:
App\DecoratingMailer:
# ...
decoration_inner_name: App\DecoratingMailer.wooz
arguments: ['@App\DecoratingMailer.wooz']
<service
id="App\DecoratingMailer"
decorates="App\Mailer"
decoration-inner-name="original_mailer"
public="false"
>
<argument type="service" id="original_mailer"/>
</service>

.. code-block:: xml
<!-- if you decorate a lot of services, consider adding the full
original service ID as part of the new ID -->
<service
id="App\DecoratingMailer"
decorates="App\Mailer"
decoration-inner-name="App\Mailer.original"
public="false"
>
<argument type="service" id="App\Mailer.original"/>
</service>

<!-- 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 https://symfony.com/schema/dic/services/services-1.0.xsd">

<services>
<!-- ... -->

<service
id="App\DecoratingMailer"
decorates="App\Mailer"
decoration-inner-name="App\DecoratingMailer.wooz"
public="false"
>
<argument type="service" id="App\DecoratingMailer.wooz"/>
</service>
</services>
</container>

</services>
</container>
.. code-block:: php

.. code-block:: php
// config/services.php
namespace Symfony\Component\DependencyInjection\Loader\Configurator;

// config/services.php
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
use App\DecoratingMailer;
use App\Mailer;

use App\DecoratingMailer;
use App\Mailer;
return function(ContainerConfigurator $container): void {
$services = $container->services();

return function(ContainerConfigurator $container): void {
$services = $container->services();
$services->set(Mailer::class);

$services->set(Mailer::class);
$services->set(DecoratingMailer::class)
->decorate(Mailer::class, 'original_mailer')
->args([service('original_mailer')]);

$services->set(DecoratingMailer::class)
->decorate(Mailer::class, DecoratingMailer::class.'.wooz')
->args([service(DecoratingMailer::class.'.wooz')]);
};
// if you decorate a lot of services, consider adding the full
// original service ID as part of the new ID
$services->set(DecoratingMailer::class)
->decorate(Mailer::class, DecoratingMailer::class.'.original')
->args([service(DecoratingMailer::class.'.original')]);
};

.. deprecated:: 6.3

The ``#[MapDecorated]`` attribute is deprecated since Symfony 6.3.
Instead, use the
:class:`#[AutowireDecorated] <Symfony\\Component\\DependencyInjection\\Attribute\\AutowireDecorated>` attribute.

.. note::

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.

.. note::

All custom :doc:`service tags </service_container/tags>` from the decorated
service are removed in the new service. Only certain built-in service tags
defined by Symfony are retained: ``container.service_locator``, ``container.service_subscriber``,
``kernel.event_subscriber``, ``kernel.event_listener``, ``kernel.locale_aware``,
and ``kernel.reset``.

Decoration Priority
-------------------
Expand Down