Цикл зависимостей между аннотированными привязками в Dagger в Kotlin - PullRequest
1 голос
/ 05 апреля 2020

Контекст

У меня есть Android приложение, написанное на Kotlin с использованием Dagger (v. 2.27). В своих тестах я создаю реальные экземпляры некоторых зависимостей и некоторых из этих зависимостей @Inject a CoroutineDispatcher.

Цель

Разрешить в моих тестах опционально указывать тест CoroutineDispatcher для использования тестовым компонентом Кинжала. Некоторые тесты не нуждаются в такой дополнительной конфигурации, и они должны автоматически получать предопределенный диспетчер тестов.

Как

У меня есть модуль, который предоставляет @BindsOptionalOf для @TestIODispatcher CoroutineDispatcher.

  • Когда для теста требуется пользовательский диспетчер, он может вручную связать его с фабрикой TestComponent.
  • Когда тесту не нужен какой-либо специальный диспетчер, он должен автоматически получить TestCoroutineDispatcher () .
@Module
abstract class RepositoryTestModule {
    @Retention(AnnotationRetention.RUNTIME)
    annotation class TestIODispatcher

    @BindsOptionalOf
    @TestIODispatcher
    abstract fun testIODispatcher(): CoroutineDispatcher

    @Module
    companion object {

        @Provides
        @IODispatcher
        fun coroutineDispatcher(
            @TestIODispatcher testIODispatcher: Optional<CoroutineDispatcher>): CoroutineDispatcher {
            return testIODispatcher.orElse(TestCoroutineDispatcher())
        }
    }
}

В моем тесте я создаю TestComponent с фабрикой, которая принимает @BindsInstance @TestIODispatcher.

@Singleton
@Component(modules = [RepositoryTestModule::class])
interface TestComponent {
    fun inject(...)

    @Component.Factory
    interface Factory {
        fun create(
            @BindsInstance @TestIODispatcher ioDispatcher: CoroutineDispatcher) : TestComponent
    }
}

Я передаю свой собственный диспетчер только для тестирования в качестве аргумента фабрика во время определения компонента.

DaggerAppNameViewModelTest_TestComponent
  .factory()
  .create(Dispatchers.IO)

Проблема

Компиляция моего теста завершается с ошибкой [Dagger / DependencyCycle].

public static abstract interface TestComponent {
                           ^
  java.util.Optional<kotlinx.coroutines.CoroutineDispatcher> is injected at
      com.example.<appname>.repository.RepositoryTestModule.Companion.coroutineDispatcher(testIODispatcher)
  kotlinx.coroutines.CoroutineDispatcher is injected at
  ...  

Я не совсем вижу цикл зависимости, поскольку мой @IODispatcher CoroutineDispatcher зависит от @TestIODispatcher CoroutineDispatcher, который явно связан с тестом.

Моя теория состоит в том, что Kotlin каким-то образом удаляет аннотации, а затем он просто сравнивает привязки по типам. В этом случае действительно был бы цикл.

Я пропустил очевидный цикл или мне нужно что-то сделать с аннотациями?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...