Skip to content
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

Documented the "auto_alias" feature #5444

Merged
merged 7 commits into from
Jul 16, 2015
Merged
Changes from 4 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
115 changes: 115 additions & 0 deletions reference/dic_tags.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ Tag Name Usage
`assetic.formula_resource`_ Adds a resource to the current asset manager
`assetic.templating.php`_ Remove this service if PHP templating is disabled
`assetic.templating.twig`_ Remove this service if Twig templating is disabled
`auto_alias`_ Define aliases based on the value of container parameters
`console.command`_ Add a command
`data_collector`_ Create a class that collects custom data for the profiler
`doctrine.event_listener`_ Add a Doctrine event listener
Expand Down Expand Up @@ -227,6 +228,120 @@ assetic.templating.twig
The tagged service will be removed from the container if
``framework.templating.engines`` config section does not contain ``twig``.

auto_alias
----------

.. versionadded:: 2.7
The ``auto_alias`` tag was introduced in Symfony 2.7.

**Purpose**: Define aliases based on the value of container parameters
Copy link
Member

Choose a reason for hiding this comment

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

you have to add a versionadded 2.7 just after the title

Copy link
Member Author

Choose a reason for hiding this comment

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

I totally forgot! Thanks for the heads-up. Fixed.


Consider the following configuration that defines three different but related
services:

.. configuration-block::

.. code-block:: yaml

services:
app.mysql_lock:
class: AppBundle\Lock\MysqlLock
app.postgresql_lock:
class: AppBundle\Lock\PostgresqlLock
app.sqlite_lock:
class: AppBundle\Lock\SqliteLock

Copy link
Member

Choose a reason for hiding this comment

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

remove this empty line (double empty line)

.. 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.mysql_lock" class="AppBundle\Lock\MysqlLock" />
<service id="app.postgresql_lock" class="AppBundle\Lock\PostgresqlLock" />
<service id="app.sqlite_lock" class="AppBundle\Lock\SqliteLock" />
Copy link
Member

Choose a reason for hiding this comment

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

these service should probably be private, so that the ones not aliased as app.lock will get removed when optimizing the container.
If you use auto-aliasing to choose the implementation, you should never access app.mysql_lock directly in your codebase anyway.

Copy link
Member Author

Choose a reason for hiding this comment

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

Indeed it's a good idea to do that. I've made services private and added a note about that. Thanks!

Copy link
Member

Choose a reason for hiding this comment

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

@javiereguiluz Seems like you didn't push that change.

Copy link
Member Author

Choose a reason for hiding this comment

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

It should be done at javiereguiluz@4c50cb0 but maybe I made a mistake when pushing 😕

Copy link
Member

Choose a reason for hiding this comment

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

Now that I look at this again, the same code blocks appear below this again with the services being private. I understand why you did that, but do we really need to do that? I mean we do repeat a lot of code this way.

</services>
</container>

.. code-block:: php

$container
->register('app.mysql_lock', 'AppBundle\Lock\MysqlLock')
->register('app.postgresql_lock', 'AppBundle\Lock\PostgresqlLock')
->register('app.sqlite_lock', 'AppBundle\Lock\SqliteLock')
;

Instead of dealing with these three services, your application needs a generic
``app.lock`` service. This service must be an alias to any of the other services.
Thanks to the ``auto_alias`` option, you can automatically create that alias
based on the value of a configuration parameter.

Considering that a configuration parameter called ``database_type`` exists,
the generic ``app.lock`` service can be defined as follows:

.. configuration-block::

.. code-block:: yaml

services:
app.mysql_lock:
class: AppBundle\Lock\MysqlLock
public: false
app.postgresql_lock:
class: AppBundle\Lock\PostgresqlLock
public: false
app.sqlite_lock:
class: AppBundle\Lock\SqliteLock
public: false
app.lock:
tags:
- { name: auto_alias, format: "app.%database_type%.lock" }

.. 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.mysql_lock" public="false"
class="AppBundle\Lock\MysqlLock" />
<service id="app.postgresql_lock" public="false"
class="AppBundle\Lock\PostgresqlLock" />
<service id="app.sqlite_lock" public="false"
class="AppBundle\Lock\SqliteLock" />

<service id="app.lock">
<tag name="auto_alias" format="app.%database_type%.lock" />
</service>
</services>
</container>

.. code-block:: php

$container
->register('app.mysql_lock', 'AppBundle\Lock\MysqlLock')->setPublic(false)
->register('app.postgresql_lock', 'AppBundle\Lock\PostgresqlLock')->setPublic(false)
->register('app.sqlite_lock', 'AppBundle\Lock\SqliteLock')->setPublic(false)

->register('app.lock')
->addTag('auto_alias', array('format' => 'app.%database_type%.lock'))
;

The ``format`` parameter defines the expression used to construct the name of
the service to alias. This expression can use any container parameter (as usual,
wrapping their names with ``%`` characters).

.. note::

When using the ``auto_alias`` tag is not mandatory to define the aliased
Copy link
Member

Choose a reason for hiding this comment

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

[...] tag it is not [...]

Copy link
Member Author

Choose a reason for hiding this comment

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

I've fixed this and the other suggestions. Thanks.

services as private. However, doing that (like in the above example) makes
sense most of the times to prevent accessing those services directly instead
of using the generic service.

console.command
---------------

Expand Down