Имеется три пакета: 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-методам модулей компонентов, который находятся ниже по иерархической цепочке зависимостей (более одного компонента)?
Ответ
Проблема была в том, что компонент 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
Комментариев нет:
Отправить комментарий