Skip to content

Docs for referencing tagged services in config #8404

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 our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Oct 13, 2017
Merged
Changes from 5 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
91 changes: 91 additions & 0 deletions service_container/tags.rst
Original file line number Diff line number Diff line change
Expand Up @@ -405,3 +405,94 @@ The double loop may be confusing. This is because a service can have more
than one tag. You tag a service twice or more with the ``app.mail_transport``
tag. The second foreach loop iterates over the ``app.mail_transport``
tags set for the current service and gives you the attributes.

Reference Tagged Services
~~~~~~~~~~~~~~~~~~~~~~~~~

.. versionadded:: 3.4
Support for the tagged service notation in YAML, XML and PHP was introduced
in Symfony 3.4.

Symfony provides a shortcut to inject all services tagged with a specific tag,
which is a common need in some applications, so you don't have to write a
compiler pass just for that. The only downside of this feature is that you can't
have any custom attributes.

In the following example, all services tagged with ``app.handler`` are passed as
first constructor argument to the ``App\HandlerCollection`` service:

.. configuration-block::

.. code-block:: yaml

services:
Copy link
Member

Choose a reason for hiding this comment

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

missing filename comment (same for the other formats):

# app/config/services.yml

App\Handler\One:
Copy link
Member

Choose a reason for hiding this comment

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

I think we should still use examples from the AppBundle namespace

Copy link
Member

Choose a reason for hiding this comment

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

That's right. We'll remove AppBundle in 4.0, but we must still use it in 3.4.

tags: [app.handler]

App\Handler\Two:
tags: [app.handler]

App\HandlerCollection:
# inject all services tagged with app.handler as first argument
arguments: [!tagged app.handler]
Copy link
Member

Choose a reason for hiding this comment

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

Let's put a comment here describing that this is passing all services tagged with app.handler as an array argument to this class. (Same for the other formats)


.. code-block:: 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\Handler\One">
<tag name="app.handler" />
</service>

<service id="App\Handler\Two">
<tag name="app.handler" />
</service>

<service id="App\HandlerCollection">
<!-- inject all services tagged with app.handler as first argument -->
<argument type="tagged" tag="app.handler" />
</service>
</services>
</container>

.. code-block:: php

use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;

$container->register(\App\Handler\One::class)
->addTag('app.handler');

$container->register(\App\Handler\Two::class)
->addTag('app.handler');

$container->register(\App\HandlerCollection::class)
Copy link
Member

Choose a reason for hiding this comment

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

the leading backslash should be removed eveyrwhere

// inject all services tagged with app.handler as first argument
->addArgument(new TaggedIteratorArgument('app.handler'));

After compilation the ``HandlerCollection`` service is able to iterate over your
application handlers.

.. code-block:: php

class HandlerCollection
Copy link
Member

Choose a reason for hiding this comment

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

missing namespace and filename comment

{
public function __construct(iterable $handlers)
{
}
Copy link
Member

Choose a reason for hiding this comment

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

This block should be moved 4 spaces to the left (the .. code-block:: php part should be in column 0)

}

.. tip::

The collected services can be prioritized using the ``priority`` attribute.
Copy link
Member

Choose a reason for hiding this comment

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

the sentence could end with a colon


.. code-block:: yaml
Copy link
Member

Choose a reason for hiding this comment

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

We are missing XML and PHP examples. :)


Copy link
Member

Choose a reason for hiding this comment

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

trailing blank line should be removed

services:
App\Handler\One:
tags:
- { name: app.handler, priority: 20 }