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

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

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

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

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


person Cativail    schedule 27.01.2015    source источник


Ответы (3)


Вы должны поместить объявление класса @Singletonto 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 {
}

Это новые требования, появившиеся в последнем выпуске моментального снимка. Это обсуждалось в соответствующем выпуске и может быть изменено.

person Kirill Boyarshinov    schedule 29.01.2015
comment
@AlexanderVasiljev Протестировано на последнем снимке. Работает нормально =). Немного обновил мой ответ с пользовательской аннотацией AScope. Что-то не так с вашим кодом. Покажи это. Кстати, давайте говорить по-английски, это не русский ресурс. - person Kirill Boyarshinov; 29.01.2015
comment
чистое решение, сэр - person pratham kesarkar; 10.07.2016

Добавлять

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

}

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

person sonal balekai    schedule 09.11.2017

Похоже на ошибку в последней версии Dagger-2: https://github.com/google/dagger/issues/107

person Alexander Vasiljev    schedule 29.01.2015