Версия на английском

Существуют 2 способа связи компонентов в Dagger: Subcomponents и Component Dependencies и каждый из них имеет свои преимущества.

Например, при использовании подхода Subcomponents весь код генерируется в :app модуле и это может привести к ошибке компиляции вроде “cannot access SomeClass” из-за транзитивной зависимости на этот класс. Component dependencies может быть использован для решения такой проблемы. Подробнее об этом можно прочитать в статье Lock your Dagger in Gradle Modules.

Hilt базируется на подходе subcomponents и описание этих компонентов скрыто от нас, поэтому мы не можем добавить зависимость на внешний компонент. Давайте посмотрим, как это можно обойти.

Предположим, у нас есть 2 gradle модуля :app -> :feature и есть независимый dagger component в :feature модуле (здесь только чистый Dagger, нет плагина и зависимостей для Hilt) который мы хотим добавить как component dependency в иерархию компонентов Hilt.

// :feature module
@Singleton
@Component
interface SomeFeatureComponent {
    fun someFeature(): SomeFeature
}

Для этого можно создать «proxy» Hilt модуль, который будет хранить в себе внешний компонент и предоставлять зависимости в граф Hilt. Теперь `someFeature` из внешнего dagger component’а может быть инжектирована через Hilt везде, где вам потребуется в :app модуле.

// :app module
@Module
@InstallIn(SingletonComponent::class)
internal class SomeFeatureProxyModule {

    // Pass as method args any dependencies from :app you need to build component
    @Singleton
    @Provides
    fun someFeatureComponent(application: Application): SomeFeatureComponent {
        return DaggerSomeFeatureComponent.builder().build()
    }

    // Use someFeature in Hilt
    @Provides
    fun someFeature(someFeatureComponent: SomeFeatureComponent): SomeFeature {
        return someFeatureComponent.someFeature()
    }
}

Стоит заметить, что это решение работает не только для Hilt, но для и подхода через subcomponents в целом. Когда вы не используете Hilt и вручную описываете граф, вы можете определить зависимости только для корневого компонента, аннотированного  @Component, но для любого дочернего компонента, аннотированного @Subcomponent такой возможности уже нет. Тем не менее, можно добавить @Module к @Subcoponent и использовать описанный обходной путь.

Исходный код доступен на GitHub

Комментарии (0)