Dagger 2 sottocomponenti vs dipendenze del componente

Il metodo plus() Dagger 1 è qualcosa che ho usato abbastanza spesso nelle applicazioni precedenti, quindi comprendo le situazioni in cui potresti voler avere un sottocomponente con accesso completo ai collegamenti dei grafici padre.

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

Dipendenze dei componenti: utilizzare questo quando:

  • vuoi mantenere due componenti indipendenti.
  • vuoi mostrare esplicitamente quali dipendenze da un componente sono usate dall’altro

Sottocomponenti: utilizzare questo quando:

  • vuoi mantenere due componenti coesivi
  • potresti non interessarti a mostrare esplicitamente quali dipendenze da un componente sono usate dall’altro

Proverò a mostrarlo e ad esempio. Dato che abbiamo i seguenti moduli e classi. SomeClassB1 dipende da SomeClassA1 . Si noti 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 della dipendenza del componente di seguito:

  • SomeClassB1 dipende da 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 da SomeClassA1 . ComponentB non ha bisogno di 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); } } 

Secondo la documentazione :

Component Dependency consente di accedere solo ai binding esposti come metodi di provisioning tramite dipendenze dei componenti, ovvero si ha accesso solo ai tipi dichiarati nel Component padre.

SubComponent ti fornisce un accesso all’intero grafico di binding dal suo genitore quando viene dichiarato, ovvero hai accesso a tutti gli oggetti dichiarati nei suoi Module .

Diciamo che hai un ApplicationComponent contiene tutte le cose relative ad Android ( 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 manca in DataComponent è Application Context che risiede in ApplicationComponent . Il modo più semplice per ottenere un Context da DataComponent sarebbe una dipendenza da ApplicationComponent . Devi essere sicuro di avere un Context esplicitamente dichiarato in ApplicationComponent perché hai solo accesso alle cose dichiarate. In questo caso, non vi è alcun lavoro manuale, il che significa che non è necessario specificare i Submodules nel Component genitore e aggiungere esplicitamente il sottomodulo a un modulo genitore come:

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

Considerate ora il caso in cui volete iniettare WebService da DataComponent e LocationService da ApplicationComponent nel vostro Fragment che si lega usando la funzione @Submodule plus sopra. La cosa interessante è che il componente a cui stai vincolando ( ApplicationComponent ) non ha bisogno di esporre WebServiceLocationService perché hai accesso a tutto il grafico subito.

Un’altra cosa che non avevo ancora capito fino ad ora è che:

  • Un’istanza @Subcomponent ha esattamente un componente padre (anche se componenti diversi possono creare un’istanza dello stesso componente @Subcomponent ed essere il padre di @Subcomponent )
  • A @Component può avere zero, uno o più componenti principali dichiarati tramite dipendenze dei componenti

Ecco l’esempio di codice con screenshot per una maggiore comprensione di Component e SubComponent:

Componente: inserisci la descrizione dell'immagine qui

  1. AppComponent contiene due dichiarazioni.
  2. AppComponent si inizializza nella class App.
  3. HomeAttivitàComponent dipende da AppComponent.
  4. In HomeActivity sull’inizializzazione di DaggerHomeActivityComponent, sto dando object AppComponent come una composizione.

Sottocomponente:

inserisci la descrizione dell'immagine qui

  1. AppComponent contiene SubComponent o SubComponents.
  2. AppComponent si inizializza nella class App.
  3. SubComponent non sa del suo ParentComponent. Questo fornisce solo le sue dipendenze includendo il modulo.
  4. In HomeActivity sto iniettando SubComponent usando il suo componente padre.

E il diagramma pittorico: inserisci la descrizione dell'immagine qui

Fonte: link