Страницы

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

среда, 22 мая 2019 г.

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

Имеется три пакета: 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

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

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