Dependencias de 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 de a SomeClassA1
través del provideSomeClassA1()
método.
SomeClassB1
no se puede crear sin SomeClassA1
. ModuleB
puede proporcionar una instancia de SomeClassB1
solo si una instancia de SomeClassA1
se pasa como argumento al provideSomeClassB1()
método.
@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 al provideSomeClassB1()
método ModuleB
cuando se inicie la declaración de Componente / Subcomponente 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 dependencies
método de @Component
anotación.
ComponentA
no necesita declarar ModuleB
. 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 ModuleA
, no puede vivir de forma independiente. Se vuelve dependiente del componente que proporcionará el ModuleA
. Por lo tanto, tiene una @Subcomponent
anotación.
ComponentA
ha declarado a ModuleB
través del método de interfaz componentB()
. Esto hace que los dos componentes estén acoplados. De hecho, ComponentB
solo se puede inicializar a través de ComponentA
.
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);
}
}
SomeClassB1
depende deSomeClassA1
.ComponentA
tiene que definir explícitamente la dependencia". ==> ¿ha querido decir "ComponentB
tiene que definir explícitamente la dependencia"?SomeClassB1
depende deSomeClassA1
.ComponentA
No necesita definir explícitamente la dependencia". querías decir "ComponentB
no es necesario que defina explícitamente la dependencia".De acuerdo con la documentación :
Component Dependency
le da acceso solo a los enlaces expuestos como métodos de provisión a través de las dependencias de los componentes, es decir, solo tiene acceso a los tipos que se declaran en padreComponent
.SubComponent
te da acceso a todo gráfico de enlace desde su padre cuando se declara, es decir, tiene acceso a todos los objetos declarados en suModule
s.Digamos Vamos, usted tiene una
ApplicationComponent
que contiene todaAndroid
la materia relacionada (LocationService
,Resources
,SharedPreference
, etc.). También desea tener su lugarDataComponent
donde administra las cosas para la persistencia junto con elWebService
manejo de las API. Lo único que te faltaDataComponent
es enApplication Context
qué resideApplicationComponent
. La forma más sencilla de obtener unaContext
desdeDataComponent
sería una dependenciaApplicationComponent
. Debe asegurarse de tener unaContext
declaración explícitaApplicationComponent
porque solo tiene acceso a las cosas declaradas. En este caso, no hay trabajo manual, lo que significa que no necesita especificarSubmodules
en el padreComponent
y agregar explícitamente su submódulo a un módulo padre como:Consideremos ahora que el caso en el que desea inyectar
WebService
desdeDataComponent
yLocationService
entreApplicationComponent
en susFragment
que se une utilizando la@Submodule
plus
característica anterior. Lo bueno aquí es que el componente al que está vinculando (ApplicationComponent
) no necesita exponerWebService
niLocationService
porque tiene acceso a todo el gráfico de inmediato.fuente
@Submodule
. ¿Es un error tipográfico?classes
como ejemplos y más imágenes para ilustrar el punto exacto.Aquí está el ejemplo de código con captura de pantalla para una mejor comprensión de Componente y Subcomponente:
Componente:
Subcomponente:
Y el diagrama pictórico:
Fuente: enlace
fuente
Otra cosa de la que no me había dado cuenta hasta ahora es que:
@Subcomponent
instancia tiene exactamente un componente principal (aunque diferentes componentes pueden crear una instancia de ese mismo@Subcomponent
y ser el principal de esa instancia)@Component
puede tener cero, uno o muchos componentes "primarios" declarados a través de dependencias de componentesfuente