2015-04-12 14 views
86

Il metodo plus() di Dagger 1 è stato utilizzato molto spesso nelle applicazioni precedenti, quindi capisco le situazioni in cui si potrebbe desiderare di avere un sottocomponente con accesso completo ai collegamenti dei grafici padre.Dagger 2 sottocomponenti contro le dipendenze dei componenti

In quale situazione sarebbe vantaggioso utilizzare un componente dipendenza invece di una dipendenza sottocomponente e perché?

risposta

166

componenti Dipendenze - Utilizzare questo quando:

  • si desidera mantenere due componenti indipendenti.
  • si vuole mostrare in modo esplicito ciò che dipendenze da un componente viene utilizzato dagli altri

sottocomponenti - Utilizzare questa funzione quando:

  • si desidera mantenere due componenti coesa
  • si potrebbe non cura per mostrare esplicitamente quale dipendenza da un componente viene utilizzata dall'altro

Proverò a mostrare questo e l'esempio. Dato che abbiamo i seguenti moduli e classi.SomeClassB1 dipende da SomeClassA1. Notare il metodo provideSomeClassB1 in ModuleB che mostra questa dipendenza.

@Module 
public class ModuleA { 
    @Provides 
    public SomeClassA1 provideSomeClassA1() { 
     return new SomeClassA1(); 
    } 
} 

@Module 
public class ModuleB { 
    @Provides 
    public SomeClassB1 provideSomeClassB1(SomeClassA1 someClassA1) { 
     return new SomeClassB1(someClassA1); 
    } 
} 

public class SomeClassA1 { 
    public SomeClassA1() {} 
} 

public class SomeClassB1 { 
    private SomeClassA1 someClassA1; 

    public SomeClassB1(SomeClassA1 someClassA1) { 
     this.someClassA1 = someClassA1; 
    } 
} 

Nota i seguenti punti nell'esempio Dipendenza Componente seguito:

  • SomeClassB1 dipende SomeClassA1. ComponentB deve definire esplicitamente la dipendenza.
  • ComponentA non ha bisogno di dichiarare ModuleB. Ciò mantiene indipendenti le due componenti.
public class ComponentDependency { 
    @Component(modules = ModuleA.class) 
    public interface ComponentA { 
     SomeClassA1 someClassA1(); 
    } 

    @Component(modules = ModuleB.class, dependencies = ComponentA.class) 
    public interface ComponentB { 
     SomeClassB1 someClassB1(); 
    } 

    public static void main(String[] args) { 
     ModuleA moduleA = new ModuleA(); 
     ComponentA componentA = DaggerComponentDependency_ComponentA.builder() 
       .moduleA(moduleA) 
       .build(); 

     ModuleB moduleB = new ModuleB(); 
     ComponentB componentB = DaggerComponentDependency_ComponentB.builder() 
       .moduleB(moduleB) 
       .componentA(componentA) 
       .build(); 
    } 
} 

Nota i seguenti punti nell'esempio Sottocomponente:

  • SomeClassB1 dipende SomeClassA1. ComponentB non è necessario definire esplicitamente la dipendenza.
  • ComponentA deve dichiarare ModuleB. Questo rende accoppiati i due componenti.
public class SubComponent { 
    @Component(modules = ModuleA.class) 
    public interface ComponentA { 
     ComponentB componentB(ModuleB moduleB); 
    } 

    @Subcomponent(modules = ModuleB.class) 
    public interface ComponentB { 
     SomeClassB1 someClassB1(); 
    } 

    public static void main(String[] args) { 
     ModuleA moduleA = new ModuleA(); 
     ComponentA componentA = DaggerSubComponent_ComponentA.builder() 
       .moduleA(moduleA) 
       .build(); 

     ModuleB moduleB = new ModuleB(); 
     ComponentB componentB = componentA.componentB(moduleB); 
    } 
} 
+4

Ho una configurazione sottocomponente che non aggiunge Modulo B a Componenta, che poi significa che il costruttore Componenta non ha bisogno moduleB. Questo sembra funzionare come mi aspettavo permettendo la creazione di ComponentA all'avvio dell'applicazione e quindi l'istanziazione di m – FriendlyMikhail

+0

Non credo che sia necessario dichiarare ModuleB nell'annotazione di ComponentA. In questo modo è possibile creare un'istanza di ComponentA all'avvio dell'applicazione e quindi creare ComponentBs con ambito, ad esempio per richiesta o per attività. Sembra funzionare in modo molto simile a come "plusing" ha funzionato in Dagger1 – FriendlyMikhail

+2

@MikeN - Puoi evidenziare come puoi sbarazzarti di ModuleB su ComponentA? Posso sbarazzarmi di ModuleB su ComponentA solo se fornisco ambiti diversi su ComponentA e ComponentB. –

35

Secondo il documentation:

Component Dependency permette di accedere solo alle legature esposte come modalità di erogazione attraverso le dipendenze dei componenti, vale a dire si ha accesso a solo i tipi che sono dichiarate nel genitore Component.

Submodules ti dà l'accesso a tutta la grafico vincolante dal suo genitore, quando viene dichiarato, vale a dire si dispone di un accesso a tutti gli oggetti dichiarati nelle sue Module s.

Diciamo, si dispone di un ApplicationComponent contenente tutte Android roba correlata (LocationService, Resources, SharedPreference, ecc). Vuoi anche avere il tuo DataComponent dove gestisci le cose per la persistenza insieme a WebService per gestire le API. L'unica cosa che ti manca in DataComponent è Application Context che risiede in ApplicationComponent. Il modo più semplice per ottenereda DataComponent è una dipendenza da ApplicationComponent. Devi essere sicuro di avere un 012 esplicitamente dichiarato in ApplicationComponent perché hai solo accesso ai contenuti dichiarati. In questo caso, non c'è lavoro manuale, il che significa che non è necessario specificare Submodules nel genitore Component ed esplicitamente aggiungere il modulo ad un modulo genitore come:

MySubcomponent mySubcomponent = myComponent.plus(new ChildGraphModule("child!")); // No need! 

Ora considerare che caso in cui si desidera iniettare WebService da DataComponent e LocationService da ApplicationComponent a Fragment che si lega utilizzando la funzione @Submoduleplus in alto. La cosa interessante è che il componente a cui si sta legando (ApplicationComponent) non è non, non è necessario esporre WebServiceLocationService perché si ha accesso all'intero grafico subito.

Problemi correlati