Tagged services
Per indicare che un servizio svolge un particolare ruolo in Symfony è possibile configurarlo aggiungendo uno o più tags alla sua definizione. Per esempio, etichettando un servizio con il tag twig.extension si indica a Symfony che il servizio deve essere trattato come una estensione di twig.
Questo meccanismo è ampiamente usato in Symfony (vedere qui l’elenco di tutti tag disponibili nel core https://symfony.com/doc/current/reference/dic_tags.html) e può essere personalizzato per le proprie necessità.
Come utilizzarli
Supponiamo di voler costruire una classe in cui vogliamo iniettare una categoria di servizi, per esempio per fornire una serie di regole da applicare in fase di esecuzione.
Per esempio, pensiamo ad una classe che possa applicare due politiche di sconto differenti in base alle caratteristiche del cliente.
Imposteremo le classi in questo modo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
//la classe per scegliere la politica di prezzo da applicare namespace PoliticaDiSconto; class PoliticaDiScontoContext { public function __construct(iterable $politicheDiSconto) { // } } //le due politiche di sconto da applicare (con relativa interface) namespace PoliticaDiSconto; interface ScontoPolicy { public function supports(Cliente $cliente): bool; public function getPercentualeSconto(): int; } namespace PoliticaDiSconto; class ScontoNormale implements ScontoPolicy { public function supports(Cliente $cliente): bool { // } public function getPercentualeSconto(): int { // } } namespace PoliticaDiSconto; class ScontoHappyHour implements ScontoPolicy { public function supports(Cliente $cliente): bool { // } public function getPercentualeSconto(): int { // } } |
Le due implementazioni di ScontoPolicy dovranno essere iniettate in ScontoContext. I due servizi dovranno essere taggati, per esempio, con il tag app.politiche_di_sconto
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<?xml version="1.0" ?> <container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> <services> <defaults autowire="true" autoconfigure="true" public="false"/> <service id="PoliticaDiSconto\ScontoNormale"> <tag name="app.politiche_di_sconto"/> </service> <service id="PoliticaDiSconto\ScontoHappyHour"> <tag name="app.politiche_di_sconto"/> </service> </services> </container> |
Per iniettarli in PoliticaDiScontoContext sarà a questo punto sufficiente impostare un parametro di tipo tagged nella definizione di servizio di quest’ultima classe.
1 2 3 |
<service id="PoliticaDiSconto\PoliticaDiScontoContext"> <argument type="tagged" tag="app.politiche_di_sconto" /> </service> |