Skip to content

Commit

Permalink
Improved "optional argument" documentation"
Browse files Browse the repository at this point in the history
Expanded the documentation for the "on invalid" behaviors for optional
arguments.
  • Loading branch information
dantleech committed Apr 27, 2016
1 parent bbec4cc commit f5329b7
Showing 1 changed file with 72 additions and 11 deletions.
83 changes: 72 additions & 11 deletions book/service_container.rst
Original file line number Diff line number Diff line change
Expand Up @@ -744,15 +744,75 @@ Injecting the dependency by the setter method just needs a change of syntax:
and "setter injection". The Symfony service container also supports
"property injection".

Making References optional
Making References Optional
--------------------------

Sometimes, one of your services may have an optional dependency, meaning
that the dependency is not required for your service to work properly. In
the example above, the ``app.mailer`` service *must* exist, otherwise an exception
will be thrown. By modifying the ``app.newsletter_manager`` service definition,
you can make this reference optional. The container will then inject it if
it exists and do nothing if it doesn't:
you can make this reference optional, there are two strategies for doing this.

Setting Missing Dependencies to null
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If you want to explicitly set the argument to ``null`` in the event that the
service does not exist then you may use the ``null`` strategy as follows:

.. configuration-block::

.. code-block:: xml
<!-- app/config/services.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.mailer">
<!-- ... -->
</service>
<service id="app.newsletter_manager" class="AppBundle\Newsletter\NewsletterManager">
<argument type="service" id="app.mailer" on-invalid="null" />
</service>
</services>
</container>
.. code-block:: php
// app/config/services.php
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\ContainerInterface;
$container->setDefinition('app.mailer', ...);
$container->setDefinition('app.newsletter_manager', new Definition(
'AppBundle\Newsletter\NewsletterManager',
array(
new Reference(
'app.mailer',
ContainerInterface::NULL_ON_INVALID_REFERENCE
)
)
));
.. note::

The "null" strategy is not currently supported by the YAML driver.

Ignoring Missing Dependencies
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The behavior of ignoring missing dependencies is the same as the "null"
behavior, except when used within a method call, in which case the method call
itself will be removed.

In the following example the container will inject the service if it exists
and ommit the argument if it doesn't:

.. configuration-block::

Expand All @@ -779,7 +839,9 @@ it exists and do nothing if it doesn't:
</service>
<service id="app.newsletter_manager" class="AppBundle\Newsletter\NewsletterManager">
<argument type="service" id="app.mailer" on-invalid="ignore" />
<call method="setMailer">
<argument type="service" id="my_mailer" on-invalid="ignore"/>
</call>
</service>
</services>
</container>
Expand All @@ -794,13 +856,12 @@ it exists and do nothing if it doesn't:
$container->setDefinition('app.mailer', ...);
$container->setDefinition('app.newsletter_manager', new Definition(
'AppBundle\Newsletter\NewsletterManager',
array(
new Reference(
'app.mailer',
ContainerInterface::IGNORE_ON_INVALID_REFERENCE
)
)
'AppBundle\Newsletter\NewsletterManager'
))->addMethodCall('setMailer', array(
new Reference(
'my_mailer',
ContainerInterface::IGNORE_ON_INVALID_REFERENCE
),
));
In YAML, the special ``@?`` syntax tells the service container that the dependency
Expand Down

0 comments on commit f5329b7

Please sign in to comment.