К сожалению, квалифицированные привязки (привязки, использующие аннотации квалификаторов, такие как @Named
), на самом деле не имеют запасной вариант или значение по умолчанию.Каждая привязка различна, и разные привязки не считаются связанными.Это затрудняет написание резервной логики, как вы просили.
Это также имеет смысл: @Named("Porsche") Engine
и @Named("Lawnmower") Engine
никогда не заменят друг друга, несмотря на общий базовый тип.Это совершенно разные зависимости, и если вам не хватает @Named("Porsche") Engine
, Dagger следует политике, согласно которой он должен терпеть неудачу во время компиляции , а не искать несоответствующий или неквалифицированный Engine.
В отличие от этого, вы можете связать карту или использовать Multibindings , чтобы указать заменяемость или гибкость, которые вы ищете.Вместо внедрения самой привязки вы добавляете карту или фабрику, которая инкапсулирует карту и извлекает правильную привязку для вас.
// This uses Multibindings, but you could manually create a Map instead.
@Binds @IntoMap @StringKey("Child1")
abstract BaseClass provideChild1(Child1 child1);
@Binds @IntoMap @StringKey("Child2")
abstract BaseClass provideChild2(Child2 child2);
// Then in your consumer...
@Inject Map<String, BaseClass> mapOfBaseClasses;
@Inject BaseClass baseClass;
// Or make an injectable Factory:
public class YourClassFactory {
private final Map<String, Provider<BaseClass>> baseClassMap;
private final Provider<BaseClass> baseClassProvider;
@Inject public YourClassFactory(/* ... */) { /* set fields */ }
public BaseClass get(String key) { /* write fallback logic here */ }
}
Если у вас есть конкретная привязка, которая может присутствоватьили отсутствует, вы также можете использовать @BindsOptionalOf
, чтобы указать, что привязка может отсутствовать во время компиляции, а затем вы можете обнаружить ее во время выполнения.
@BindsOptionalOf @Named("Child3")
abstract BaseClass provideOptionalOfChild3();
// Then in your consumer:
private final BaseClass baseClass;
@Inject public YourConsumer(
@Named("Child3") Optional<BaseClass> optionalChild3,
Provider<BaseClass> defaultBaseClass) {
baseClass =
optionalChild3.isPresent()
? optionalChild3.get()
: defaultBaseClass.get();
}