Dagger 2 per sviluppatori Android inesperti. Pugnale 2.Parte 2
Questo articolo è la quinta parte di una serie di articoli destinati, secondo l'autore, a coloro che non riescono a capire come gestire l' iniezione di dipendenza e il framework Dagger 2 , o semplicemente lo faranno. Originale scritto il 17 dicembre 2017. Traduzione gratis.

Questo è il quinto articolo della serie Dagger 2 per sviluppatori Android principianti. ... Se non hai letto i precedenti, allora sei qui .
Questa dipendenza viene fornita utilizzando il modello
Abbiamo detto a Dagger 2 di ottenere queste dipendenze usando un'annotazione
Non è successo niente? Sì, non hai ricevuto alcun errore, ma prova a eseguire il progetto. Dovresti ricevere il seguente errore:

Se leggi il testo dell'errore, allora dice chiaramente che i metodi
Come accennato in precedenza, Dagger 2 semplifica il rilevamento dei bug. Puoi giocare un po' con questa classe. Annotazioni
Scaviamo più a fondo e ci occupiamo di un paio di annotazioni utili -
In breve, questa annotazione contrassegna moduli e classi. Parliamo di Android. Possiamo avere un modulo
In breve, questa annotazione è necessaria per contrassegnare i metodi che forniscono dipendenze all'interno dei moduli. Nell'esempio descritto in precedenza, abbiamo contrassegnato la classe
Dai un'occhiata a un piccolo esempio (link al ramo ).
Torna in classe
Il prossimo articolo uscirà il 29 dicembre o più tardi. Grazie per la vostra pazienza.

Questo è il quinto articolo della serie Dagger 2 per sviluppatori Android principianti. ... Se non hai letto i precedenti, allora sei qui .
Serie di articoli
- Dagger 2 per sviluppatori Android inesperti. Introduzione.
- Dagger 2 per sviluppatori Android inesperti. Iniezione di dipendenza. Parte 1 .
- Dagger 2 per sviluppatori Android inesperti. Iniezione di dipendenza. Parte 2 .
- Dagger 2 per sviluppatori Android inesperti. Pugnale 2.Parte 1 .
- Dagger 2 per sviluppatori Android inesperti. Pugnale 2. Parte 2 (sei qui) .
- Dagger 2 per sviluppatori Android inesperti. Pugnale 2. Livello avanzato.
Parte 1 . - Dagger 2 per sviluppatori Android inesperti. Pugnale 2. Livello avanzato.
Parte 2.
All'inizio della serie
Nell'articolo precedente, abbiamo discusso di come l'uso manuale di Dependency Injection (DI) aggiunga complessità e codice standard. Dopo aver esaminato come Dagger 2 ci allevia da questo dolore e genera codice standard per noi. Abbiamo anche esaminato i processori di annotazione e le annotazioni di base di Dagger 2. Quindi abbiamo applicato queste annotazioni tramite l'esempio e abbiamo inserito le dipendenze utilizzando Dagger 2.Anatomia di un DaggerBattleComponent
Per una migliore comprensione di Dagger 2, considera la classeDaggerBattleComponent
... Posiziona il cursore suDaggerBattleComponent
e premi Ctrl + B (o Ctrl + LMB, Comando + LMB). Vedrai quanto segue:@Generated (
value = "dagger.internal.codegen.ComponentProcessor",
comments = "https://google.github.io/dagger"
)
public final class DaggerBattleComponent implements BattleComponent {
private DaggerBattleComponent (Builder builder) {}
public static Builder builder () {
return new Builder ();
}
public static BattleComponent create () {
return new Builder (). build ();
}
// implemented interface method
@Override
public War getWar () {
return new War (new Starks (), new Boltons ());
}
public static final class Builder {
private Builder () {}
public BattleComponent build () {
return new DaggerBattleComponent (this);
}
}
}
Questo è ciò che Dagger 2 genera per noi per risolvere il problema della dipendenza difficile . Se guardi l'interfaccia implementata dalla classe, vedrai che lo èBattleComponent
- l'interfaccia che abbiamo creato in precedenza e descritto il metodo in essagetWar()
per fornire un'istanza della classeWar
...Questa dipendenza viene fornita utilizzando il modello
builder
... È di moda leggere di più su questo modello qui e qui .Impariamo qualcosa di nuovo
Spero che tu capisca chiaramente perché il metodo è necessariogetWar()
... Ora voglio aggiungere un altro paio di dipendenze:Starks
eBoltons
... Aggiungiamo metodi all'interfaccia:@Component
interface BattleComponent {
War getWar ();
// add methods
Starks getStarks ();
Boltons getBoltons ();
}
Dopo aver apportato le modifiche, ricostruire il progetto. Ora controlliamo la classeDaggerBattleComponent
... Se hai fatto tutto correttamente, vedrai quanto segue.@Generated(
value = "dagger.internal.codegen.ComponentProcessor",
comments = "https://google.github.io/dagger"
)
public final class DaggerBattleComponent implements BattleComponent {
private DaggerBattleComponent(Builder builder) {}
public static Builder builder() {
return new Builder();
}
public static BattleComponent create() {
return new Builder().build();
}
@Override
public War getWar() {
return new War(getStarks(), getBoltons());
}
@Override
public Starks getStarks() {
return new Starks();
}
@Override
public Boltons getBoltons() {
return new Boltons();
}
public static final class Builder {
private Builder() {}
public BattleComponent build() {
return new DaggerBattleComponent(this);
}
}
}
Come puoi vedere, Dagger 2 ha implementato i metodigetStarks()
egetBoltons()
...Abbiamo detto a Dagger 2 di ottenere queste dipendenze usando un'annotazione
@Inject
in classeBoltons
... Rompiamo qualcosa. Rimuovi annotazione@Inject
dalla classeBoltons
... Ricostruisci il progetto.Non è successo niente? Sì, non hai ricevuto alcun errore, ma prova a eseguire il progetto. Dovresti ricevere il seguente errore:

Se leggi il testo dell'errore, allora dice chiaramente che i metodi
getWar()
egetBoltons()
non funzionerà se non ci sono segni di annotazione@Inject
o@Provides
...Come accennato in precedenza, Dagger 2 semplifica il rilevamento dei bug. Puoi giocare un po' con questa classe.
Annotazioni@Module
e@Provides
Scaviamo più a fondo e ci occupiamo di un paio di annotazioni utili -@Module
e@Provides
... Vale la pena usarli se il tuo progetto sta crescendo di dimensioni.@Module
In breve, questa annotazione contrassegna moduli e classi. Parliamo di Android. Possiamo avere un moduloContextModule
e questo modulo fornirà le dipendenzeApplicationContext
eContext
per altre classi. Per fare ciò, dobbiamo contrassegnare la classeContextModule
annotazione@Module
...@Provides
In breve, questa annotazione è necessaria per contrassegnare i metodi che forniscono dipendenze all'interno dei moduli. Nell'esempio descritto in precedenza, abbiamo contrassegnato la classeContextModule
annotazione@Module
, ma dobbiamo anche contrassegnare i metodi che forniscono dipendenzeApplicationContext
eContext
annotazione@Provides
...Dai un'occhiata a un piccolo esempio (link al ramo ).
Esempio
Prendiamo due servizi forniti da Braavos - Contanti e Soldati (non sono sicuro che forniscano un tale servizio, ma consideralo solo come esempio). Creiamo due classi:public class Cash {
public Cash () {
// something happens
}
}
public class Soldiers {
public Soldiers () {
// something happens
}
}
Ora creiamo un modulo e gli diamo un nomeBraavosModule
... Ci fornirà due dipendenze:Cash
eSoldiers
...@Module // Module
public class BraavosModule {
Cash cash;
Soldiers soldiers;
public BraavosModule (Cash cash, Soldiers soldiers) {
this.cash = cash;
this.soldiers = soldiers;
}
@Provides // Provides the Cash dependency
Cash provideCash () {
return cash;
}
@Provides // Provides the Soldiers dependency
Soldiers provideSoldiers () {
return soldiers;
}
}
Come abbiamo visto in precedenza, è necessario contrassegnare tutti i moduli con un'annotazione@Module
e i metodi che forniscono le dipendenze sono annotati@Provides
...Torna in classe
BattleOfBastards
e dire al componente di implementare i metodiprovideCash()
eprovideSoldiers()
...@Component(modules = BraavosModule.class)
interface BattleComponent {
War getWar();
Cash getCash();
Soldiers getSoldiers();
}
public class BattleOfBastards {
public static void main (String [] args) {
Cash cash = new Cash ();
Soldiers soldiers = new Soldiers ();
BattleComponent component = DaggerBattleComponent
.builder ()
.braavosModule (new BraavosModule (cash, soldiers))
.build ();
War war = component.getWar ();
war.prepare ();
war.report ();
// use money and soldiers
component.getCash ();
component.getSoldiers ();
}
}
Nota che il modulo è stato aggiunto alla dichiarazione di annotazione@Component
... Ciò significa che il componente conterrà questo modulo al suo interno.@Component(modules = BraavosModule.class)
Dopo tutte le modifiche, ricostruisci il progetto. Vedrai un errore nel metodo.create()
classeDaggerBattleComponent
... È nato dal fatto che quando si aggiunge un modulo, questa dipendenza deve essere passata a Dagger 2. Si presenta così:BattleComponent component = DaggerBattleComponent.builder().braavosModule(new BraavosModule(cash, soldiers)).build();
Dopo aver abilitato tutti i moduli, puoi iniziare a utilizzare i loro metodi tramiteComponent
...component.getCash(); component.getSoldiers();
Se vuoi essere sicuro, passa il cursore sopraDaggerBattleComponent
e premi Ctrl + B (o Ctrl + LMB, Comando + LMB). Vedrai che il moduloBraavosModule
incluso nella classe per fornire le dipendenzeCash
eSoldiers
...Sommario
Abbiamo analizzato le classi generate da Dagger 2 e abbiamo notato che Dagger 2 utilizza il templatebuilder
per fornire dipendenze. Abbiamo anche visto un semplice esempio di utilizzo delle annotazioni@Module
e@Provides
...Qual è il prossimo?
Nel prossimo articolo, esamineremo un'applicazione Android di esempio che utilizza Dagger 2.Il prossimo articolo uscirà il 29 dicembre o più tardi. Grazie per la vostra pazienza.