Service Method Calls and Setter Injection

Version: 4.4
Edit this page

Service Method Calls and Setter Injection

Tip

If you're using autowiring, you can use @required to 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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// src/Service/MessageGenerator.php
namespace App\Service;

use Psr\Log\LoggerInterface;

class MessageGenerator
{
    private $logger;

    public function setLogger(LoggerInterface $logger): void
    {
        $this->logger = $logger;
    }

    // ...
}

To configure the container to call the setLogger method, use the calls key:

  • YAML
  • XML
  • PHP
1
2
3
4
5
6
# config/services.yaml
services:
    App\Service\MessageGenerator:
        # ...
        calls:
            - setLogger: ['@logger']

New in version 4.3

The immutable-setter injection was introduced in Symfony 4.3.

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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// src/Service/MessageGenerator.php
namespace App\Service;

use Psr\Log\LoggerInterface;

class MessageGenerator
{
    private $logger;

    /**
     * @return static
     */
    public function withLogger(LoggerInterface $logger): self
    {
        $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:

  • YAML
  • XML
  • PHP
1
2
3
4
5
6
# config/services.yaml
services:
    App\Service\MessageGenerator:
        # ...
        calls:
            - withLogger: !returns_clone ['@logger']
This work, including the code samples, is licensed under a Creative Commons BY-SA 3.0 license.