Como digo ao Dagger 2 qual implementação instanciar com base no X?
Dentro de um módulo, se eu precisar fornecer uma implementação diferente de uma interface com base em uma variável conhecida no momento da construção do módulo, posso colocar a lógica dentro do método @Provides para esse tipo de interface. Igual a:
@Module
public class FooModule {
private final State state;
public FooModule(State state) {
this.state = state;
}
@Provides
FooInterface provideFooImplementation() {
switch(state) {
case STATE_1:
return new FooImpl1();
case STATE_2:
return new FooImpl2();
...
case STATE_10:
return new FooImpl10();
}
}
}
No entanto, essas implementações podem ser criadas por Dagger. Prefiro dizer "Ei, com base no X, quero que você instancie essa aula para mim"
Eu considerei algumas opções.
Altere o método fornece para incluir todas as implementações possíveis:
@Provides
FooInterface provideFooImplementation(FooImpl1 impl1, FooImpl2 imp2, ..., FooImpl10 impl10) {
switch(state) {
case STATE_1:
return impl1;
case STATE_2:
return impl2;
...
case STATE_10:
return impl10;
}
}
Isso permite que o Dagger os instancie e satisfaça todas as suas dependências, mas não é uma boa idéia se cada uma das implementações for relativamente grande ou cara de criar.
Altere o método fornece para coletar todas as dependências das diferentes implementações.
@Provides
FooInterface provideFooImplementation(Context context, Repo repo, HttpClient httpClient, ...) {
switch(state) {
case STATE_1:
return new FooImpl1(context);
case STATE_2:
return new FooImpl2(repo, httpClient);
...
case STATE_10:
return new FooImpl10(context, repo);
}
}
Isso é um pouco melhor que a opção 1, pois o Dagger não precisa instanciar todas as implementações, mas ainda precisa instanciar todas as dependências, mesmo que elas não possam ser usadas em todos os casos. Também estou voltando a criar os objetos, mesmo que eles possam ser criados por Dagger.
Crie um módulo por implementação e instancie o módulo apropriado. Então, algo como:
@Module
public FooImpl1Module {
@Provides
FooInterface provideFooImplementation(Context context) {
return new FooImpl1(context);
}
}
Isso seria bom, mas agora tenho problemas ao definir o componente que depende do módulo.
Qual é a melhor maneira de resolver esse problema?
Uma sugestão foi tentar a opção 1 com os parâmetros agrupados no Lazy. Então acabo chamando .get () em um. Vou tentar quando puder e postar os resultados