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:
SomeClassA1Se puede crear sin ninguna dependencia. ModuleAproporciona una instancia de a SomeClassA1través del provideSomeClassA1()método.
SomeClassB1no se puede crear sin SomeClassA1. ModuleBpuede proporcionar una instancia de SomeClassB1solo si una instancia de SomeClassA1se 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 SomeClassA1como argumento al provideSomeClassB1()método ModuleBcuando 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:
ComponentBtiene que definir la dependencia a través del dependenciesmétodo de @Componentanotación.
ComponentAno 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
ComponentBno 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 @Subcomponentanotación.
ComponentAha declarado a ModuleBtravés del método de interfaz componentB(). Esto hace que los dos componentes estén acoplados. De hecho, ComponentBsolo 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);
}
}
SomeClassB1depende deSomeClassA1.ComponentAtiene que definir explícitamente la dependencia". ==> ¿ha querido decir "ComponentBtiene que definir explícitamente la dependencia"?SomeClassB1depende deSomeClassA1.ComponentANo necesita definir explícitamente la dependencia". querías decir "ComponentBno es necesario que defina explícitamente la dependencia".De acuerdo con la documentación :
Component Dependencyle 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.SubComponentte da acceso a todo gráfico de enlace desde su padre cuando se declara, es decir, tiene acceso a todos los objetos declarados en suModules.Digamos Vamos, usted tiene una
ApplicationComponentque contiene todaAndroidla materia relacionada (LocationService,Resources,SharedPreference, etc.). También desea tener su lugarDataComponentdonde administra las cosas para la persistencia junto con elWebServicemanejo de las API. Lo único que te faltaDataComponentes enApplication Contextqué resideApplicationComponent. La forma más sencilla de obtener unaContextdesdeDataComponentsería una dependenciaApplicationComponent. Debe asegurarse de tener unaContextdeclaración explícitaApplicationComponentporque solo tiene acceso a las cosas declaradas. En este caso, no hay trabajo manual, lo que significa que no necesita especificarSubmodulesen el padreComponenty agregar explícitamente su submódulo a un módulo padre como:Consideremos ahora que el caso en el que desea inyectar
WebServicedesdeDataComponentyLocationServiceentreApplicationComponenten susFragmentque se une utilizando la@Submodulepluscaracterística anterior. Lo bueno aquí es que el componente al que está vinculando (ApplicationComponent) no necesita exponerWebServiceniLocationServiceporque tiene acceso a todo el gráfico de inmediato.fuente
@Submodule. ¿Es un error tipográfico?classescomo 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:
@Subcomponentinstancia tiene exactamente un componente principal (aunque diferentes componentes pueden crear una instancia de ese mismo@Subcomponenty ser el principal de esa instancia)@Componentpuede tener cero, uno o muchos componentes "primarios" declarados a través de dependencias de componentesfuente