Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

[DependencyInjection] Add documentation about service decoration#3753

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Closed
Changes fromall 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
92 changes: 92 additions & 0 deletionscomponents/dependency_injection/advanced.rst
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -185,3 +185,95 @@ the service itself gets loaded. To do so, you can use the ``file`` directive.

Notice that Symfony will internally call the PHP statement ``require_once``,
which means that your file will be included only once per request.

Decorating Services
-------------------

.. versionadded:: 2.5
Decorated services were introduced in Symfony 2.5.

When overriding an existing definition, the old service is lost:

.. code-block:: php

$container->register('foo', 'FooService');

// this is going to replace the old definition with the new one
// old definition is lost
$container->register('foo', 'CustomFooService');

Most of the time, that's exactly what you want to do. But sometimes,
you might want to decorate the old one instead. In this case, the
old service should be kept around to be able to reference it in the
new one. This configuration replaces ``foo`` with a new one, but keeps
a reference of the old one as ``bar.inner``:

.. configuration-block::

.. code-block:: yaml

bar:
public: false
class: stdClass
decorates: foo
arguments: ["@bar.inner"]

.. code-block:: xml

<service id="bar" class="stdClass" decorates="foo" public="false">
<argument type="service" id="bar.inner" />
</service>

.. code-block:: php

use Symfony\Component\DependencyInjection\Reference;

$container->register('bar', 'stdClass')
->addArgument(new Reference('bar.inner'))
->setPublic(false)
->setDecoratedService('foo');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I would prefer if we usedDefinition andContainer#setDefinition here


Here is what's going on here: the ``setDecoratedService()` method tells
the container that the ``bar`` service should replace the ``foo`` service,
renaming ``foo`` to ``bar.inner``.
By convention, the old ``foo`` service is going to be renamed ``bar.inner``,
so you can inject it into your new service.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

What about usingfoo andbar as the service names? I guess, that would make thing more clear. With the current situation, people might think that the names of the decorated service and that of the decorating service must be the same except of the1.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

👍


Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

foo andbar are sooo confusing! Wouldn't it be better to use a real world example, let's say arouter ?

We would haverouter,router.inner andcustom_router f.e.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Yes, in fact, why not use a real service from the framework? Sure, this is the components, butany service we choose here will be "invented", so why not use on that's a real service somewhere.

.. note::
The generated inner id is based on the id of the decorator service
(``bar`` here), not of the decorated service (``foo`` here). This is
mandatory to allow several decorators on the same service (they need to have
different generated inner ids).

Most of the time, the decorator should be declared private, as you will not
need to retrieve it as ``bar`` from the container. The visibility of the
decorated ``foo`` service (which is an alias for ``bar``) will still be the
same as the original ``foo`` visibility.

You can change the inner service name if you want to:

.. configuration-block::

.. code-block:: yaml

bar:
class: stdClass
public: false
decorates: foo
decoration_inner_name: bar.wooz
arguments: ["@bar.wooz"]

.. code-block:: xml

<service id="bar" class="stdClass" decorates="foo" decoration-inner-name="bar.wooz" public="false">
<argument type="service" id="bar.wooz" />
</service>

.. code-block:: php

use Symfony\Component\DependencyInjection\Reference;

$container->register('bar', 'stdClass')
->addArgument(new Reference('bar.wooz'))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

missing use statement

->setPublic(false)
->setDecoratedService('foo', 'bar.wooz');

[8]ページ先頭

©2009-2025 Movatter.jp