La dependency injection consiste sostanzialmente nel fornire gli oggetti di cui un oggetto ha bisogno (le sue dipendenze) invece di farli costruire da solo.  Le dipendenze possono essere iniettate negli oggetti con molti mezzi (come l’iniezione del costruttore o l’iniezione del setter). 

In Laravel è presente un sistema di “autowiring” che permette di instanziare la dipendenza in modo automatico senza doverla dichiarare espressamenteQuesta definizione può sembrare molto astratta e complicata, ma in realtà è un concetto molto semplice, come vedremo nell’esempio. Capiamo inoltre perché utile capire tutto questo. 

La dependency injection è utile specialmente per i test. La classe iniettata può essere rappresentata da una classe “mock”, cioè una classe fittizia dove nel test andiamo a descrivere i metodi e il comportamento che ci aspettiamo.

Esempio pratico

Supponiamo di avere un controller per la creazione di un utente. Questo controller ha un metodo “create” che si aspetta due campi dalla request: email e password. Il controller passa questi valori a una classe “repository” che si occupa di inserire il record nel database.

 

Per semplicità evitiamo qualsiasi validazione.

Come vedi l’oggetto repository è passato tramite il costruttore e viene assegnato a un’attributo del controller. Questo poi viene utilizzato dal metodo create() del controller a riga 21.

Anche la request è passata tramite dependency injection, ma questa volta nel metodo create. La classe request è instanziata e valorizzata automaticamente da Laravel. 

Esempio di uno unit test

Gli oggetti passati tramite dependency injection possono essere rappresentati da oggetti mock, nei quali descriviamo il comportamento che ci aspettiamo. Possiamo ad esempio creare uno scenario in cui il repository fallisce, o uno scenario in cui la creazione dell’utente va a buon fine, come mostrato nell’esempio seguente.

dependency iniection laravel

Nota che il codice della nostra applicazione che verrà effettivamente eseguito è esclusivamente quello del controller. Ecco perché per scrivere unit test la dependency injection è così importante.

Come vedi nella mock definiamo quali metodi sono richiamati dal controller, quante volte, con quali parametri e infine cosa ci aspettiamo che il metodo restituisca. (Vedi riga 16 e 23).

Conclusione

Speriamo con questo articolo di averti schiarito le idee su come la dependency injection funziona. Ti incoraggiamo a provare a utilizzarla scrivendo degli unit test per la tua applicazione.

Per una definizione più teorica e completa, ti consigliamo di leggere l’articolo di Martin Fowler che dà una spiegazione più generalizzata, ma esaustiva di cosa consiste la dependency injection.