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
YAML
-
XML
XML
-
PHP
PHP
1 2 3 4 5 6 |
# config/services.yaml
services:
App\Service\MessageGenerator:
# ...
calls:
- setLogger: ['@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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
// src/Service/MessageGenerator.php
namespace App\Service;
use Psr\Log\LoggerInterface;
class MessageGenerator
{
private $logger;
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
YAML
-
XML
XML
-
PHP
PHP
1 2 3 4 5 6 |
# config/services.yaml
services:
App\Service\MessageGenerator:
# ...
calls:
- withLogger: !returns_clone ['@logger']
|
Tip
If autowire is enabled, you can also use attributes; with the previous example it would be:
1 2 3 4 5 6 7 8 9 10 11 |
/**
* @return static
*/
#[Required]
public function withLogger(LoggerInterface $logger)
{
$new = clone $this;
$new->logger = $logger;
return $new;
}
|
You can also leverage the PHP 8 static
return type instead of the
@return static
annotation. If you don't want a method with a
PHP 8 static
return type and a #[Required]
attribute to behave as
a wither, you can add a @return $this
annotation to disable the
returns clone feature.