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 1 commit
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
89 changes: 89 additions & 0 deletions service_container/tags.rst
Original file line number Diff line number Diff line change
Expand Up @@ -405,3 +405,92 @@ 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
Copy link
Member

Choose a reason for hiding this comment

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

"Reference Tagged Services" (title case uppercases almost every word, except when there are closed words)

~~~~~~~~~~~~~~~~~~~~~~~~~

In case your tag doesn't require any further additional attributes writing compiler
passes per tag might become tedious. A way to overcome this is is to make your compiler
pass more generic. The downside of this approach is you have to write and maintain
additional code, considering you want to reuse it over multiple projects.
Copy link
Member

Choose a reason for hiding this comment

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

I don't think we need so much information and we're kinda missing the complete feature here: Using tags to inject a list of services to another service. Tags can do non-injecting stuff as well. What about saying something like: (change at your free will 😄 )

If you use tags to inject a list of services as an argument, writing a compiler pass is a bit tedious. As this is a very common case, Symfony provides a way to inject all services tagged with a specific tag. The downside of this feature is that you can't have any custom attributes. In the example below, all services tagged with app.handler are passed in an array as the first constructor argument to the App\\HandlerCollection service:

Copy link
Contributor

Choose a reason for hiding this comment

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

agree. this text is good as a blog post introducing this new feature as it explains the thought process. but it does not fit as a feature documention


ThereBecause this task is so generic and common to do, Symfony provides a way to achieve this
directly in your service container confguration. This enables to inject services tagged
with e.g. `app.handler` into another service that collects all handlers.
Copy link
Member

Choose a reason for hiding this comment

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

Inline code blocks should be surrounded by double backticks (single backticks are used for references)


.. 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:
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">
<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\One::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

->addArgument(new TaggedIteratorArgument('app.handler'));

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

.. code-block:: php

class HandlerCollection
{
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.

.. 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. :)


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

.. versionadded:: 3.4

Copy link
Member

Choose a reason for hiding this comment

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

This line should be removed (versionadded is a really strange directive). And let's move this to just below the section title

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

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