Подтвердить что ты не робот

Проблемы с синглтонами при использовании компонентных зависимостей

У меня возникла проблема в понимании того, почему следующий код не работает.

У меня есть следующая структура проекта:

@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()

То, к чему я стремлюсь, состоит в том, чтобы один компонент наследовал привязки от других компонентов, чтобы иметь одинаковые ссылки на объекты (одиночные числа).

4b9b3361

Ответ 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 и все еще может быть изменен.

Ответ 3

Добавить

@Singleton
@Component(modules = {NameModule.class})
public interface NameComponent {

}

для компонента, потому что dagger2 не позволяет использовать компоненты с немодулированными областями с областью действия модулей