Проблемы с синглтонами при использовании компонентных зависимостей
У меня возникла проблема в понимании того, почему следующий код не работает.
У меня есть следующая структура проекта:
@Component(modules = CCModule.class)
public interface CComponent {
XXX getXXX();
}
где
@Module
public class CCModule {
@Provides @Singleton
public XXX provide XXX(){
return new XXX();
}
}
и
@Component(dependencies = CComponent.class, modules = AAModule.class)
public interface AComponent {
YYY getYYY();
}
где
class YYY {
@Inject
public YYY(XXX xxx) {
...
}
}
Я инициализирую все как:
CComponent c_component = Dagger_CComponent.builder().cCModule(new CCModule()).build();
AComponent a_component = Dagger_AComponent.builder()
.cComponent(c_component)
.aAModule(new AAModule())
.build();
После компиляции я получаю следующую ошибку:
Ошибка: (11, 1) ошибка: com.test.CComponent(unscoped) не может привязки с привязкой к привязке: @Provides @Singleton com.test.XXX com.test.CCModule.provideXXX()
То, к чему я стремлюсь, состоит в том, чтобы один компонент наследовал привязки от других компонентов, чтобы иметь одинаковые ссылки на объекты (одиночные числа).
Ответы
Ответ 1
Вы должны поместить объявление @Singleton
в CComponent
.
@Singleton
@Component(modules = CCModule.class)
public interface CComponent {
XXX getXXX();
}
Объяснение находится в сообщении об ошибке: CComponent
не облагается, @Singleton
- область. Dagger 2 не позволяет компонентам, не облажаемым областью, использовать модули с привязанными областями.
Однако теперь вы получите следующую ошибку:
AComponent (unscoped) cannot depend on scoped components:
@Component(dependencies = CComponent.class, modules = AModule.class)
Недоступные компоненты не могут иметь зависимые области. Поэтому вам нужно сделать область AComponent
. Для этого создайте пользовательскую аннотацию AScope
.
@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface AScope {
}
И добавьте в него комментарий AComponent
:
@AScope
@Component(dependencies = CComponent.class, modules = AModule.class)
public interface AComponent {
}
Это новые требования, появившиеся в последней версии моментального снимка. Он обсуждался в соответствующем issue и все еще может быть изменен.
Ответ 2
Похож на ошибку в последней версии Dagger-2:
https://github.com/google/dagger/issues/107
Ответ 3
Добавить
@Singleton
@Component(modules = {NameModule.class})
public interface NameComponent {
}
для компонента, потому что dagger2 не позволяет использовать компоненты с немодулированными областями с областью действия модулей