Inversion of control e Dependency Injection

Introduzione alla dependency injection

Dependency Injection (DI) e Inversion Of Control (IoC) sono due elementi fondamentali per lo sviluppo di applicazioni “moderne”. A prima vista possono sembrare due concetti complessi ma, una volta appresi i principi, difficilmente si potrà farne a meno.

Il problema da risolvere è la dipendenza tra oggetti

Analizziamo il seguente codice:

dove Engine e Car accettono come parametro del loro costruttore un oggetto di tipo Generator. Il codice è perfettamente funzionante, anche se i singoli construttori dipendono dall’implementazione specifica dell’oggetto Generator.

Dal codice precedente possiamo estrarre l’interfaccia per la classe Engine:

e definire la classe facendola ereditare dall’interfaccia stessa:

L’utilizzo dell’interfaccia è fondamentale perchè consente di generare oggetti che implementeranno tutti con la stessa firma. L’utilizzo dell’interfaccia consente di definire una sorta di “contratto” con tutte le classi che la implementeranno.

A questo punto la classe Car può essere modificata nel seguente modo:

A questo punto la classe Car accetterà in ingresso oggetti che implementano la classe IEngine, senza fornire il tipo specifico.

Nell’ottica di centralizzare la risoluzione dell’oggetto da istanziare viene utilizzato l’IoC. Possiamo considerarlo (semplificando le sue funzionalità) come un meccanismo nel quale effettuare la registrazione delle corrispondenze tra interfacce e tipi che le implementano. Ad esempio:

Ogni volta che l’interfaccia IEngine viene richiesta, dovrà essere sostituita da Engine. Utilizzando ad esempio Autofac (uno dei tanti IoC disponibili) la sintassi che dovrà essere utilizzata è la seguente:

Dopo aver creato l’oggetto ContainerBuilder viene eseguita la registrazione delle corrispondenze tra tipi. Successivamente viene creato il container (con le rules indicate in precedenza).

E’ possibile istanziare manualmente l’oggetto associato all’interfaccia utilizzando:

I vantaggi

  • Testabilità del codice: utilizzando le interfacce risulta piuttosto semplice creare implementazioni di oggetti “mock” per testare il codice
  • Disaccopiamento: le classi sono disaccopiate, secondo il principio che ogni classe dovrebbe eseguire un singolo compito ed essere il più “isolata” possibile

L’utilizzo di Dependency Injection (DI) e Inversion Of Control (IoC) avviene solitamente in ambienti più complessi di quello descritto in precedenza.

 

Pubblicato da

Andrea Merlin

Laureato in informatica, diversi corsi di specializzazione legati allo Sviluppo Software e alla Computer forensics. Appassionato di nuove tecnologie, amo la programmazione, la Business Intelligence e tematiche legate alla Privacy.Sempre alla ricerca di nuove idee, stimoli … e progetti da seguire!Amo trascorrere il tempo libero in Val Borbera, un piccolo angolo del Piemonte, in provincia di Alessandria.