.. index:: single: DependencyInjection; Method Calls Service Method Calls and Setter Injection ========================================= .. tip:: If you're using autowiring, you can use ``@required`` to :ref:`automatically configure method calls `. Usually, you'll want to inject your dependencies via the constructor. But sometimes, especially if a dependency is optional, you may want to use "setter injection". For example:: namespace App\Service; use Psr\Log\LoggerInterface; class MessageGenerator { private $logger; public function setLogger(LoggerInterface $logger) { $this->logger = $logger; } // ... } To configure the container to call the ``setLogger`` method, use the ``calls`` key: .. configuration-block:: .. code-block:: yaml # config/services.yaml services: App\Service\MessageGenerator: # ... calls: - [setLogger, ['@logger']] .. code-block:: xml .. code-block:: php // config/services.php namespace Symfony\Component\DependencyInjection\Loader\Configurator; use App\Service\MessageGenerator; return function(ContainerConfigurator $configurator) { // ... $services->set(MessageGenerator::class) ->call('setLogger', [ref('logger')]); }; To provide immutable services, some classes implement immutable setters. Such setters return a new instance of the configured class instead of mutating the object they were called on:: namespace App\Service; use Psr\Log\LoggerInterface; class MessageGenerator { private $logger; /** * @return static */ public function withLogger(LoggerInterface $logger) { $new = clone $this; $new->logger = $logger; return $new; } // ... } Because the method returns a separate cloned instance, configuring such a service means using the return value of the wither method (``$service = $service->withLogger($logger);``). The configuration to tell the container it should do so would be like: .. configuration-block:: .. code-block:: yaml # config/services.yaml services: App\Service\MessageGenerator: # ... calls: - withLogger: !returns_clone ['@logger'] .. code-block:: xml .. code-block:: php // config/services.php use App\Service\MessageGenerator; use Symfony\Component\DependencyInjection\Reference; $container->register(MessageGenerator::class) ->addMethodCall('withLogger', [new Reference('logger')], true);