Как мне сообщить Dagger 2, какую реализацию создавать на основе X?
Внутри модуля, если мне нужно предоставить другую реализацию интерфейса, основанную на переменной, известной во время создания модуля, я могу поместить логику в метод @Provides для этого типа интерфейса. Вот так:
@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();
}
}
}
Тем не менее, эти реализации могут быть созданы Dagger. Я бы скорее сказал: «Эй, основываясь на X, я хочу, чтобы ты создал для меня этот класс»
Я рассмотрел пару вариантов.
Измените метод обеспечивает, чтобы принимать во всех возможных реализациях:
@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;
}
}
Это позволяет Dagger создавать их экземпляры и удовлетворять все их зависимости, но не очень хорошая идея, если каждая из реализаций является относительно большой или дорогой в создании.
Измените метод предоставляет, чтобы получить коллекцию всех зависимостей для различных реализаций.
@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);
}
}
Это немного лучше, чем вариант 1 в том смысле, что Dagger не должен создавать экземпляры каждой отдельной реализации, однако ему все еще нужно создавать экземпляры всех зависимостей, даже если они могут использоваться не во всех случаях. Я также вернулся к созданию объектов сам, хотя они могут быть созданы Dagger.
Создайте один модуль для каждой реализации и создайте экземпляр соответствующего модуля. Так что-то вроде:
@Module
public FooImpl1Module {
@Provides
FooInterface provideFooImplementation(Context context) {
return new FooImpl1(context);
}
}
Это было бы хорошо, но теперь у меня есть проблемы с определением компонента, который зависит от модуля.
Какой лучший способ решить эту проблему?
Одним из предложений было попробовать вариант 1 с параметрами, обернутыми в Lazy. Тогда я в итоге вызываю .get () только для одного. Я попробую это когда смогу и опубликую результаты