Страницы

Поиск по вопросам

четверг, 5 марта 2020 г.

Провайдинг зависимостей “перепрыгивая” через компонент

#java #android #dagger2


Имеется три пакета: a, b и c. Каждый из этих пакетов включает в себя интерфейс с
буквой, реализацию интерфейса, компонент, модуль и Scope (не знаю, как правильно переводится).
В результате, выходит вот такая структура проекта:

│   
│
├───a   A.java
│       AComponent.java
│       AImpl.java
│       AModule.java
│       AScope.java
│
├───b   B.java
│       BComponent.java
│       BImpl.java
│       BModule.java
│       BScope.java
│
└───c   C.java
        CComponent.java
        CImpl.java
        CModule.java
        CScope.java

Application.java


CComponent имеет зависимость (dependencies) на BComponent, а BComponent - на CComponent. 

BModule требует класс A для создания класса B, а CModule требует классы A и B для
создания класса C:

@AScope
@Component(modules = AModule.class)
public interface AComponent {
    A a();
}

@Module
public class AModule {
    @Provides
    @AScope
    public A provideA() {
        return new AImpl();
    }
}



@BScope
@Component(modules = BModule.class, dependencies = AComponent.class)
public interface BComponent {
    B b();
}

@Module
public class BModule {
    @Provides
    @BScope
    public B provideB(A a) {
        return new BImpl(a);
    }
}



@CScope
@Component(modules = CModule.class, dependencies = BComponent.class)
public interface CComponent {
    C c();
}


@Module
public class CModule {
    @Provides
    @CScope
    public C provideC(A a, B b) {
        return new CImpl(b, a);
    }
}




При попытке собрать проект, Dagger 2 начинает ругаться, что CComponent не может найти
провайдера класса A:

Error:(9, 7) java: com.dugin.rostislav.a.A cannot be provided without an @Provides-annotated
method.
      com.dugin.rostislav.a.A is injected at
          com.dugin.rostislav.c.CModule.provideC(a, …)
      com.dugin.rostislav.c.C is provided at
          com.dugin.rostislav.c.CComponent.c()




Почему компонент не может получить доступ к Provide-методам модулей компонентов,
который находятся ниже по иерархической цепочке зависимостей (более одного компонента)?
    


Ответы

Ответ 1



Проблема была в том, что компонент BComponent должен был явно указать компонентам, имеющим на него зависимости, какие реализации он может провайдить из нижестоящих компонентов. То есть он должен указать, что может дать класс A: @BScope @Component(modules = BModule.class, dependencies = AComponent.class) public interface BComponent { A a(); B b(); } Для того, чтобы пробрасывать зависимости неявно — можно использовать Subcomponent. Очень хорошая статья на хабре про Component Dependencies и Subcomponents, где раскрывается данный вопрос - Dagger 2. Часть вторая. Custom scopes, Component dependencies, Subcomponents.

Комментариев нет:

Отправить комментарий