Table des matières
- Faire un service à injecter
- Faire une interface pour injecter le service
- Faire un Trait
- Definir les services dans la configuration
Faire un service à injecter
Si j'ai un service à injecter, mais que je ne sais pas à l'avance si je vais pouvoir utiliser le constructeur, je dois trouver une autre manière de le faire
Il se pourrait que le constructeur de mon service soit déjà gros, ou encore que le service ai été crée avec une Factory...
Voici le service que je vais injecter:
<?php
namespace App\Utils;
class MyService
{
public function doSomething(): void
{
// perform operations here...
}
}
Faire une interface pour injecter le service
Pour "marquer" les services où je vais injecter MyService
, je crée une interface qui certifie que je possède un accès à MyService
via une méthode getMyService
.
<?php
namespace App\Utils;
interface MyServiceAwareInterface
{
function getMyService(): MyService;
}
Faire un Trait
Et pour ne pas à avoir à implémenter plein de fois la même logique, je fais un Trait qui sera utilisé dans mes services implémentant MyServiceAwareInterface
.
<?php
namespace App\Utils;
trait MyServiceAwareTrait
{
private $myService;
public function setMyService(MyService $myService): void
{
$this->myService = $myService;
}
public function getMyService(): MyService
{
if (!isset($this->myService)) {
throw new \RuntimeException("MyService has not been injected properly.");
}
return $this->myService;
}
}
Le Trait conserve une instance de MyService
qu'il obtient avec la méthode setMyService
et implémente getMyService
de MyServiceAwareInterface
.
Definir les services dans la configuration
Pour finir, il ne me reste plus qu'à trouver les services implémentant MyServiceAwareInterface
et à leur injecter '@App\Utils\MyService'
grâce au Trait.
services:
_instanceof:
App\Utils\MyServiceAwareInterface:
calls:
- setMyService: ['@App\Utils\MyService']
Il est aussi possible de le faire avec un CompilerPass
.
Voici un exemple de service qui implémente l'interface:
<?php
namespace App\Domain;
use App\Utils\MyServiceAwareInterface;
use App\Utils\MyServiceAwareTrait;
class ExampleService implements MyServiceAwareInterface
{
use MyServiceAwareTrait;
public function performExample(): void
{
$this->getMyService()->doSomething();
}
}