Dagger2 - приложение не может зависеть от нескольких компонентов - PullRequest
1 голос
/ 04 апреля 2019

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

Всего несколько дней назад я начал разрабатывать модульное приложение для Android. Я использую Dagger 2 для обработки внедрения зависимостей, и в настоящее время я сталкиваюсь со странным поведением. У меня есть основной модуль приложения и три других модуля:

  • Core_Module: предоставляет сторонние библиотеки и уровень хранения.
  • Localisation_Module: он предоставляет хранилище для получения локализованной информации.
  • Configuration_Module: он предоставляет хранилище для получения параметров конфигурации.

И Configuration_Module, и Localisation_Module зависят от Core_Module.

CoreComponent:

@Singleton
@Component(modules = [ApplicationModule::class, NetworkingModule::class, RepositoryModule::class])
interface CoreComponent {
    @Named("retrofit")
    fun retrofit(): Retrofit

    @Named("retrofitWithCache")
    fun retrofitWithCache(): Retrofit

    fun storageRepository(): StorageRepository
}

LocalisationComponent:

@Component(modules = [ServiceModule::class, RepositoryModule::class], dependencies = [CoreComponent::class])
@LocalisationScope
interface LocalisationComponent {
    fun localisationService(): LocalisationService
    fun localisationRepository(): LocalisationRepository
}

ConfigurationComponent

@Component(modules = [ServiceModule::class, RepositoryModule::class], dependencies = [CoreComponent::class])
@ConfigurationScope
interface ConfigurationComponent {
    fun configurationService(): ConfigurationService
    fun configurationRepository(): ConfigurationRepository
}

ApplicationComponent

@Component(dependencies = [LocalisationComponent::class, ConfigurationComponent::class])
@ApplicationScope
abstract class ApplicationComponent {
    abstract fun inject(mainActivity: MainActivity)
}

MainApplication

class MainApplication : Application() {
    lateinit var applicationComponent: ApplicationComponent

    override fun onCreate() {
        super.onCreate()
        this.registerDependencies()
    }

    private fun registerDependencies() {
        val coreModule = CoreModule(applicationContext)
        applicationComponent = DaggerApplicationComponent.builder()
                .localisationComponent(LocalisationModule(coreModule).localisationComponent)
                .configurationComponent(ConfigurationModule(coreModule).configurationComponent)
                .build()
    }
}

Я решил спроектировать эту архитектуру, потому что хочу разделить функциональные возможности на независимые, взаимозаменяемые модули, чтобы каждый из них содержал все необходимое для выполнения определенной функциональности и экспорта отдельных модулей в другие приложения.

enter image description here

К сожалению, я получил сообщение о том, что компонент Dagger не может зависеть от нескольких компонентов области действия. Кто-нибудь знает, как решить эту проблему?

1 Ответ

0 голосов
/ 05 апреля 2019

После целого дня неприятностей я нашел решение, подходящее для моего случая. Все описанные модули (Configuration_Module, Localisation_Module) необходимо использовать внутри моего прикладного модуля.

Так что для @ApplicationScope @Module под названием ApplicationModule я удалил все зависимости компонентов.

Компонент приложения

@Component(modules = [ApplicationModule::class])
@ApplicationScope
abstract class ApplicationComponent {
    abstract fun inject(mainActivity: MainActivity)
}

Прикладной модуль

@Module
class ApplicationModule(private val localisationComponent: LocalisationComponent,
                        private val configurationComponent: ConfigurationComponent) {
    @Provides
    @ApplicationScope
    fun providesLocalisationRepository(): LocalisationRepository {
        return localisationComponent.localisationRepository() // Provided by Localisation module with Dagger
    }

    @Provides
    @ApplicationScope
    fun providesConfigurationRepository(): ConfigurationRepository {
        return configurationComponent.configurationRepository() // Provided by Configuration module with Dagger
    }
}

Наконец, мое основное приложение

class MainApplication : Application() {
    lateinit var applicationComponent: ApplicationComponent

    override fun onCreate() {
        super.onCreate()
        this.registerDependencies()
    }

    private fun registerDependencies() {
        val coreModule = CoreModule(applicationContext)
        val applicationModule = ApplicationModule(LocalisationModule(coreModule).localisationComponent,
                                ConfigurationModule(coreModule).configurationComponent)

        applicationComponent = DaggerApplicationComponent.builder()
                .applicationModule(applicationModule)
                .build()
    }
}

Я указал, что все работает как шарм.

...