Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

La Dependency Injection

Delegare la creazione degli oggetti ad un agente esterno: il container
Delegare la creazione degli oggetti ad un agente esterno: il container
Link copiato negli appunti

L'idea alla base della Dependency Injection è quella di avere un componente esterno (assembler) che si occupi della creazione degli oggetti e delle loro relative dipendenze e di assemblarle mediante l'utilizzo dell'injection. In particolare esistono tre forme di injection:

  1. Constructor Injection, dove la dipendenza viene iniettata tramite l'argomento del costruttore
  2. Setter Injection, dove la dipendenza viene iniettata attraverso un metodo "set"
  3. Interface Injection che si basa sul mapping tra interfaccia e relativa implementazione (non utilizzato in Spring)

L'iniezione di dipendenza può essere realizzata in molteplici modi, tra cui il più semplice consiste nell'utilizzo di una factory. Riprendiamo ora l'esempio del generatore di report e cerchiamo di capire come realizzare una semplice iniezione della dipendenza.

Creiamo un'interfaccia Report che definisce le operazioni di base che un report deve avere e facciamola implementare alla classe TxtReport:

// Interfaccia Report
public interface Report {
  public void generate(String data);
  public void saveToFile();
}
// Classe TxtReport
public class TxtReport implements Report {
  String path;
  public TxtReport(String path) { this.path = path; }
  public void generate(String data) {
    System.out.println("genera txt report");
  }
  public void saveToFile() {
    System.out.println("File salvato!");
  }
}

Modifichiamo il ReportGenerator in modo che sia in grado di utilizzare oggetti di tipo Report e aggiungiamo il relativo metodo setter:

public class ReportGenerator {
  Report report;
  public Report generate(String data) {
    // report = new TxtReport();
    report.generate(data);
    return report;
  }
  public void setReport (Report report) {
    this.report = report;
  }
}

Creiamo infine una classe factory che avrà il compito di istanziare oggetti di tipo ReportGenerator e di risolverne le dipendenze:

public class ReportGeneratorFactory {
  public static ReportGenerator createTxtReportGenerator() {
    ReportGenerator rg = new ReportGenerator();
    rg.setReport(new TxtReport()); // risoluzione della dipendenza
    return rg;
  }
}

Il client della nostra applicazione si presenterà in questo modo:

public class ReportClient {
  public static void main(String[] args) {
    String data = null;
    // reperimento dati	
    ReportGenerator gen = ReportGeneratorFactory.createTxtReportGenerator();
    gen.generate(data).saveToFile();
  }
}

La soluzione proposta ci ha permesso di disaccopiare le classi ReportGenerator e TxtGenerator attraverso l'utilizzo della classe ReportGeneratorFactory. In particolare la factory, dopo aver creato l'oggetto ReportGenerator, vi ha iniettato attraverso il relativo metodo setter (setter injection) un oggetto di tipo Report.

Per effettuare delle prove è possibile scaricare l'esempio completo (progetto Eclipse)

Pur essendo efficace, questo tipo "manuale" di DI continua ancora a non risolvere il problema di avere scolpito nel codice la creazione del report. Il problema è infatti stato semplicemente trasferito nella classe factory, che dovrà essere ogni volta modificata se si vorrà cambiare il tipo di report da utilizzare.

Il Container

Un modo migliore per poter lavorare con la Dependency Injection è quello di utilizzare come assembler uno IoC Container in grado di compiere operazioni di injection.

Per definizione un container è un componente esterno che si prende carico di una serie di compiti esonerando così lo sviluppatore dal preoccuparsene. Uno IoC Container non è altro che un container specializzato nella dependency injection, che basandosi su apposite configurazioni definite dall'utente (generalmente attraverso l'utilizzo di un file xml) è in grado di compiere opportune operazioni di injection.

Nella prossima lezione vedremo come Spring mette a disposizione un potente IoC Container, e riprendendo l'esempio del generatore di report cercheremo di capirne il funzionamento.

Ti consigliamo anche