dagger2 - dagger 2 tutorial español
Dagger 2 subcomponentes vs dependencias de componentes (4)
Aquí está el ejemplo de código con captura de pantalla para una mejor comprensión de Componente y Subcomponente:
- AppComponent contiene dos declaraciones.
- AppComponent se inicializa en la clase de aplicación.
- HomeActivityComponent depende de AppComponent.
- En HomeActivity sobre la inicialización de DaggerHomeActivityComponent, estoy dando el objeto AppComponent como composición.
Subcomponente:
- AppComponent contiene SubComponent o SubComponents.
- AppComponent se inicializa en la clase de aplicación.
- El subcomponente no sabe acerca de su componente principal. Que solo proporciona sus propias dependencias al incluir el Módulo.
- En HomeActivity estoy inyectando un subcomponente utilizando su componente principal.
Fuente: link
El método
plus()
Dagger 1 es algo que utilicé con bastante frecuencia en aplicaciones anteriores, por lo que entiendo las situaciones en las que es posible que desee tener un subcomponente con acceso completo a los enlaces de los gráficos principales.
¿En qué situación sería beneficioso usar una dependencia de componente en lugar de una dependencia de subcomponente y por qué?
De acuerdo con la documentation :
Component Dependency
le da acceso a solo los enlaces expuestos como métodos de provisión a través de dependencias de componentes, es decir, tiene acceso a solo los tipos que se declaran en el
Component
principal.
SubComponent
le da acceso a
todo el
gráfico de enlace desde su padre cuando se declara, es decir, tiene acceso a todos los objetos declarados en su
Module
s.
Digamos que tiene un
SharedPreference
ApplicationComponent
contiene todo lo relacionado con
Android
(
LocationService
,
Resources
,
SharedPreference
, etc.).
También desea tener su
DataComponent
donde administre cosas para la persistencia junto con
WebService
para lidiar con las API.
Lo único que le falta en
DataComponent
es
Application Context
que reside en
ApplicationComponent
.
La forma más simple de obtener un
Context
de
DataComponent
sería una dependencia de
ApplicationComponent
.
Debe asegurarse de tener un
Context
declarado explícitamente en
ApplicationComponent
porque solo tiene acceso a material declarado.
En este caso, no hay trabajo manual, lo que significa que no necesita especificar
Submodules
en
Component
principal y agregar explícitamente su submódulo a un módulo principal como:
MySubcomponent mySubcomponent = myComponent.plus(new ChildGraphModule("child!")); // No need!
Ahora considere ese caso en el que desea inyectar
WebService
de
DataComponent
y
LocationService
de
ApplicationComponent
en su
Fragment
que se une usando la función
@Submodule
plus
anterior.
Lo bueno aquí es que el componente al que está vinculando (
ApplicationComponent
)
no
necesita exponer
WebService
ni
LocationService
porque tiene acceso al gráfico completo de inmediato.
Otra cosa de la que no me había dado cuenta hasta ahora es que:
-
Una instancia de
@Subcomponent
tiene exactamente un componente padre (aunque diferentes componentes pueden crear una instancia de ese mismo@Subcomponent
y ser el padre de esa instancia) -
Un
@Component
puede tener cero, uno o muchos componentes principales declarados a través de dependencias de componentes
Dependencias de los componentes: use esto cuando desee mantener dos componentes independientes.
Subcomponentes: utilícelo cuando desee mantener dos componentes acoplados.
Usaré el siguiente ejemplo para explicar las dependencias de componentes y subcomponentes . Algunos puntos que vale la pena notar sobre el ejemplo son:
-
SomeClassA1
se puede crear sin ninguna dependencia.ModuleA
proporciona una instancia deSomeClassA1
través del métodoprovideSomeClassA1()
. -
SomeClassB1
no se puede crear sinSomeClassA1
.ModuleB
puede proporcionar una instancia deSomeClassB1
solo si se pasa una instancia deSomeClassA1
como argumento para proporcionar elprovideSomeClassB1()
.
@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;
}
}
Dagger se encargará de pasar la instancia de
SomeClassA1
como argumento para
provideSomeClassB1()
método
provideSomeClassB1()
en el
ModuleB
siempre que se
ModuleB
el Componente / Subcomponente que declara el
ModuleB
Necesitamos instruir a Dagger cómo cumplir con la dependencia.
Esto se puede hacer utilizando la
dependencia del componente
o el
subcomponente
.
Dependencia de componentes
Tenga en cuenta los siguientes puntos en el ejemplo de dependencia de componentes a continuación:
-
ComponentB
tiene que definir la dependencia a través del método dedependencies
en la anotación@Component
. -
ComponentA
A no necesita declarar elModuleB
Esto mantiene los dos componentes independientes.
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();
}
}
Subcomponente
Tenga en cuenta los siguientes puntos en el ejemplo de Subcomponente:
-
Como
ComponentB
no ha definido la dependencia delModuleA
, no puede vivir de forma independiente. Se vuelve dependiente del componente que proporcionará elModuleA
. Por lo tanto, tiene una anotación@Subcomponent
. -
ComponentA
ha declaradoModuleB
través del método de interfazcomponentB()
ModuleB
componentB()
. Esto hace que los dos componentes estén acoplados. De hecho,ComponentB
solo se puede inicializar a través deComponentA
.
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);
}
}