Lazy<T>
не означает «выяснить позже, связан ли T», это означает «обеспечить привязку для T во время компиляции, но создавать экземпляр только во время выполнения после того, как я вызову get
».Вам все равно нужно будет сделать привязку для T доступной во всех случаях, но Dagger не будет пытаться создать ее экземпляр, пока вы не попросите об этом явно.
Dagger требует, чтобы она использовалась для всех случаев использования Provider<T>
и Lazy<T>
, привязка T должна существовать во время компиляции, даже если во время выполнения вы ее не вызываете.Это гарантирует, что если вы вызовете get()
для экземпляра Provider или Lazy, он не завершится с ошибкой во время выполнения для той привязки, которая, как он знал, отсутствовала во время компиляции.(Lazy ведет себя точно так же, как и Provider, за исключением того, что Lazy запоминает экземпляр, который он возвращает, независимо от того, была ли привязка ограничена.)
Это означает, что один из ваших вариантов - добавить привязку для ModelMqlBased, которую возвращает null
или выдает исключение , что обычно было бы ужасной идеей в Dagger, но этого было бы достаточно для случая, когда во время выполнения вы знаете, что метод Provides никогда не вызывается.
Другой способдостичь желаемой гибкости можно с помощью @ BindsOptionalOf .Это позволяет вам вводить Optional<T>
или Optional<Lazy<T>>
, который разрешает текущее значение, если привязка существует, и отсутствующий заполнитель, если привязка не существует.
@Module
public abstract class ModelModule {
// Note abstract class and static/abstract methods.
@BindsOptionalOf
abstract ModelMqlBased bindOptionalOfModelMqlBased();
@Provides
@ModelScope
static IModel iModel(Optional<ModelMqlBased> modelMqlBased,
ModelFileBased modelFileBased,
@Named("configClientType")String clientType) {
switch (clientType) {
case "mqlBot":
return modelMqlBased.get();
case "fileBot":
return modelFileBased;
default:
throw new RuntimeException();
}
}
}
Это может упростить повторное использованиемодулей, особенно потому, что (например, мультибиндинги) вы можете предоставить столько методов @BindsOptionalOf abstract T bindOptionalOfT();
, сколько захотите, и Dagger не будет жаловаться на дублирование.