Cos'è un container DI?
Un container dependency injection (DIC) è una classe che può istanziare e configurare oggetti.
Potrebbe sorprenderti, ma in molti casi non hai bisogno di un container dependency injection per sfruttare i vantaggi della dependency injection (abbreviato DI). Dopotutto, anche nel capitolo introduttivo abbiamo mostrato DI con esempi concreti e non era necessario alcun container.
Tuttavia, se devi gestire un gran numero di oggetti diversi con molte dipendenze, un container dependency injection sarà davvero utile. Questo è il caso, ad esempio, delle applicazioni web costruite su un framework.
Nel capitolo precedente, abbiamo introdotto le classi Article
e UserController
. Entrambe hanno alcune
dipendenze, ovvero il database e la factory ArticleFactory
. E per queste classi creeremo ora un container.
Ovviamente, per un esempio così semplice, non ha senso avere un container. Ma lo creeremo per mostrare come appare e
funziona.
Ecco un semplice container hardcoded per l'esempio fornito:
L'utilizzo sarebbe il seguente:
Chiediamo semplicemente l'oggetto al container e non dobbiamo più sapere nulla su come crearlo e quali dipendenze ha; il container sa tutto questo. Le dipendenze vengono iniettate automaticamente dal container. In questo sta la sua forza.
Per ora, il container ha tutti i dati scritti in modo fisso. Faremo quindi il passo successivo e aggiungeremo parametri per rendere il container veramente utile:
I lettori attenti potrebbero aver notato un certo problema. Ogni volta che ottengo un oggetto UserController
,
viene creata anche una nuova istanza di ArticleFactory
e del database. Questo decisamente non lo vogliamo.
Aggiungeremo quindi un metodo getService()
, che restituirà sempre le stesse istanze:
Alla prima chiamata, ad esempio $container->getService('Database')
, farà creare l'oggetto database da
createDatabase()
, lo salverà nell'array $services
e alla chiamata successiva lo restituirà
direttamente.
Modificheremo anche il resto del container per utilizzare getService()
:
A proposito, il termine servizio si riferisce a qualsiasi oggetto gestito dal container. Ecco perché anche il nome del metodo
getService()
.
Fatto. Abbiamo un container DI completamente funzionante! E possiamo usarlo:
Come vedi, scrivere un DIC non è complicato. Vale la pena ricordare che gli oggetti stessi non sanno di essere creati da un container. Di conseguenza, è possibile creare in questo modo qualsiasi oggetto in PHP senza intervenire sul suo codice sorgente.
La creazione e la manutenzione manuale della classe del container possono diventare rapidamente un incubo. Nel prossimo capitolo, parleremo quindi del Container Nette DI, che può generarsi e aggiornarsi quasi da solo.