IT knowledge base
CTRL+F per cercare la tua parola chiave

Capire il pugnale 2

Di seguito vedrai una traduzione gratuita di un articolo di Miquel Beltran pubblicato su
Medio il 12 febbraio 2016. Lo scopo dell'articolo è quello di formare una comprensione del meccanismo di base di funzionamento di Dagger 2 .
Ho scoperto che la maggior parte dei tutorial che spiegano come funziona Dagger sono eccessivamente complessi. Anche la guida di Google/Square è troppo pesante da capire se non hai una chiara comprensione di come funziona l' iniezione di dipendenza .
Per capirlo, ho creato un progetto Java molto semplice con diverse classi che mostra come funziona Dagger .
In questo articolo, spiegherò gli elementi costitutivi di base di Dagger . L'articolo è rivolto a coloro che non utilizzano questa libreria, ma stanno pianificando.

Struttura del progetto

apply plugin: 'java'

repositories {
  jcenter()
}

dependencies {
  testCompile 'junit:junit:4.12'
  compile 'com.google.dagger:dagger:2.0'
  compile 'com.google.dagger:dagger-compiler:2.0'
}
Questo è il codice per il file build.gradle . Plugin Java standard e JUnit verranno utilizzati per creare unit test. Non dimenticare di aggiungere la libreria del compilatore di pugnali alle tue dipendenze (questo è stato il mio primo errore).
Nota del puledro riguardo alla dipendenza dal compilatore pugnale:

Per Dagger ‡ e altri prodotti basati su APT, è meglio usare il plugin gradle-apt. Ciò renderà la compilazione del tuo progetto più trasparente e sicura, poiché due diversi percorsi di classe non verranno confusi: uno per compilare il codice e l'altro per generarlo.

Mostrami il codice

Questo esempio avrà due classi:
  • GameData: questa classe fornisce i dati richiesti dalla classe GameSession . Nel nostro caso, è solo una stringa.
  • GameSession: questa classe richiede GameData . Inietteremo la dipendenza usando Dagger , invece di passare GameData come parametro o istanziarlo all'interno di GameSession .
Senza l'iniezione di dipendenza, sarebbe qualcosa di simile al seguente: la classe GameData viene creata all'interno di GameSession . Alcuni sviluppatori saranno d'accordo che questa è una cattiva pratica. Ad esempio, se per il test è necessaria un'altra istanza di GameData , non sarà possibile crearne una.
public class GameData {
    public final String hello = "Hello Dagger";
}
public class GameSession {
    public GameData data = new GameData();
}
Dagger si occuperà di iniettare un'istanza della classe GameData in una variabile della classe GameSession . Devi solo indicarlo usando un'annotazione@Inject ...
public class GameData {
  public final String hello = "Hello Dagger";
}
import javax.inject.Inject;

public class GameSession {
    @Inject
    public GameData data;
}
Ora è necessario creare classi che definiranno come verrà implementata l'iniezione di dipendenza, queste sono Component e Module .
  • Il modulo definisce tutti i provider di injection. Cioè, definisce i metodi che ci restituiranno istanze concrete per l'iniezione in una classe dipendente. In questo caso, dobbiamo definire un provider che ci restituirà GameData .
  • Il componente è l'interfaccia che Dagger utilizzerà per generare il codice per iniettare le dipendenze per noi.
import dagger.Component;

@Component(modules = GameModule.class)
public interface GameComponent {
    void inject(GameSession obj);
}
import dagger.Module;
import dagger.Provides;

@Module
public class GameModule {
    @Provides
    GameData providesGameData() {
        return new GameData();
    }
}
  • GameModule contiene una funzione annotata@Provides che dice a Dagger che questa è una di quelle funzioni che restituisce un'istanza GameData .
  • È inoltre necessario contrassegnare la classe GameModule con l' annotazione@Module ...
  • L'interfaccia GameComponent definisce una funzione di iniezione. Questa funzione verrà utilizzata nella classe GameSession e vi inserirà un'istanza della classe GameData , che verrà restituita dalla funzione GameModule.providesGameData() .
Questo momento contiene tutta la magia . Dagger capirà che la classe GameSession richiede una classe GameData , che la classe GameModule determina come viene recuperata l'istanza GameData ; che è necessario utilizzare l'interfaccia GameComponent per avviare l'iniezione chiamata dalla classe GameSession .

Utilizzo del componente

Il seguente unit test mostra come inserire la classe GameData in una classe GameSession istanziata utilizzando una classe Component generata.
import org.junit.Test;
import static org.junit.Assert.*;

public class GameSessionTest {
    @Test
    public void testGameSession() {
        GameSession session = new GameSession();
        DaggerGameComponent.create().inject(session);
        assertEquals("Hello Dagger", session.data.hello);
    }
}
  1. La classe DaggerGameComponent è generata da Dagger inclusa la funzione create() .
  2. Questa classe implementa l'interfaccia GameComponent , in cui possiamo chiamare il metodo inject() e passarci un'istanza di GameSession .
  3. Il metodo inject() si occuperà di iniettare tutte le dipendenze per GameSession .
  4. Infine, possiamo vedere che il valore del campo dati della classe GameSession è impostato.

Questo esempio è semplice, mancano molte funzionalità di Dagger . Come ho detto, questo esempio mi ha aiutato a capire le basi e spero che aiuti anche te.
Ora che hai una conoscenza di base di come funziona Dagger 2 , ti consiglio di tornare alla documentazione originale e provare l'esempio di CoffeeMaker .