En ocasiones, algún servicio puede tener dependencias opcionales, lo cual significa que esas dependencias no son obligatorias para que el servicio funcione correctamente. En el ejemplo anterior, el servicio my_mailer
debe existir, ya que si no, se lanzará una excepción. Modificando la definición del servicio newsletter_manager
, puedes hacer que esta dependencia sea opcional. De esta forma, el contenedor inyectará el servicio si existe y no hará nada si el servicio inyectado no existe:
# src/Acme/HelloBundle/Resources/config/services.yml
parameters:
# ...
services:
newsletter_manager:
class: %newsletter_manager.class%
arguments: ["@?my_mailer"]
<!-- src/Acme/HelloBundle/Resources/config/services.xml -->
<services>
<service id="my_mailer" ...>
<!-- ... -->
</service>
<service id="newsletter_manager" class="%newsletter_manager.class%">
<argument type="service" id="my_mailer" on-invalid="ignore" />
</service>
</services>
// src/Acme/HelloBundle/Resources/config/services.php
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\ContainerInterface;
// ...
$container->setParameter(
'newsletter_manager.class',
'Acme\HelloBundle\Newsletter\NewsletterManager'
);
$container->setDefinition('my_mailer', ...);
$container->setDefinition('newsletter_manager', new Definition(
'%newsletter_manager.class%',
array(
new Reference(
'my_mailer',
ContainerInterface::IGNORE_ON_INVALID_REFERENCE
)
)
));
En YAML, la sintaxis especial @?
le dice al contenedor de servicios que la dependencia es opcional. Alternativamente, puedes preparar el código de la clase NewsletterManager
para que la dependencia sea opcional:
public function __construct(Mailer $mailer = null)
{
// ...
}