Dependências de componentes - use isso quando desejar manter dois componentes independentes.
Subcomponentes - use-o quando desejar manter dois componentes acoplados.
Usarei o exemplo abaixo para explicar dependências e subcomponentes de componentes . Alguns pontos dignos de nota sobre o exemplo são:
SomeClassA1
pode ser criado sem qualquer dependência. ModuleA
fornece e instância de SomeClassA1
via o provideSomeClassA1()
método
SomeClassB1
não pode ser criado sem SomeClassA1
. ModuleB
pode fornecer uma instância de SomeClassB1
somente se uma instância de SomeClassA1
for passada como um argumento para o 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;
}
}
O Dagger cuidará de passar a instância de SomeClassA1
como um argumento para o provideSomeClassB1()
método ModuleB
sempre que a declaração de Componente / Subcomponente ModuleB
for inicializada. Precisamos instruir Dagger como cumprir a dependência. Isso pode ser feito usando dependência de componente ou subcomponente .
Dependência de componentes
Observe os seguintes pontos no exemplo de dependência de componente abaixo:
ComponentB
deve definir a dependência através do dependencies
método na @Component
anotação.
ComponentA
não precisa declarar ModuleB
. Isso mantém os dois componentes independentes.
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();
}
}
SubComponent
Observe os seguintes pontos no exemplo SubComponent:
- Como
ComponentB
não definiu a dependência ModuleA
, ela não pode viver de forma independente. Torna-se dependente do componente que fornecerá o ModuleA
. Por isso, tem uma @Subcomponent
anotação.
ComponentA
declarou ModuleB
através do método de interface componentB()
. Isso torna os dois componentes acoplados. De fato, ComponentB
só pode ser inicializado via 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
tem que definir explicitamente a dependência." ==> você quis dizer "ComponentB
precisa definir explicitamente a dependência"?SomeClassB1
depende deSomeClassA1
.ComponentA
Não precisa definir explicitamente a dependência". você quis dizer "ComponentB
não precisa definir explicitamente a dependência".De acordo com a documentação :
Component Dependency
fornece acesso apenas às ligações expostas como métodos de provisionamento por meio de dependências de componentes, ou seja, você tem acesso apenas aos tipos declarados no paiComponent
.SubComponent
dá a você acesso a todo o gráfico de ligação de seu pai quando ele é declarado, ou seja, você tem acesso a todos os objetos declarados em seusModule
s.Vamos dizer, você tem uma
ApplicationComponent
contendo todasAndroid
coisas relacionadas (LocationService
,Resources
,SharedPreference
, etc). Você também quer terDataComponent
onde gerenciar coisas para persistência eWebService
lidar com APIs. A única coisa que faltaDataComponent
éApplication Context
que resideApplicationComponent
. A maneira mais simples de obter aContext
partir deDataComponent
seria uma dependênciaApplicationComponent
. Você precisa ter umaContext
declaração explícitaApplicationComponent
porque só tem acesso a itens declarados. Nesse caso, não há trabalho manual, o que significa que você não precisa especificarSubmodules
no paiComponent
e adicionar explicitamente seu submódulo a um módulo pai, como:Agora, considere que caso onde você quer injetar
WebService
a partirDataComponent
eLocationService
partirApplicationComponent
em seusFragment
que liga usando o@Submodule
plus
recurso acima. O legal aqui é que o componente ao qual você está vinculando (ApplicationComponent
) não precisa exporWebService
nemLocationService
porque você tem acesso a todo o gráfico imediatamente.fonte
@Submodule
. É um erro de digitação?classes
como exemplos e mais figuras para ilustrar o ponto exato.Aqui está o exemplo de código com captura de tela para entender melhor o Component e o SubComponent:
Componente:
Subcomponente:
E o diagrama pictórico:
Fonte: link
fonte
Outra coisa que eu ainda não tinha percebido até agora é que:
@Subcomponent
instância possui exatamente um componente pai (embora componentes diferentes possam instanciar o mesmo@Subcomponent
e ser o pai dessa instância)@Component
pode ter zero, um ou muitos componentes "principais" declarados através de dependências de componentesfonte