首页 > 解决方案 > Dagger 2 会在从 Android 层移除的纯 Kotlin 模块中工作吗?

问题描述

我正在尝试实现类似于此处描述的干净代码架构。为了强制执行它,每一层都是 Android Studio 中的一个独立模块,具有依赖链,因此:

模型(纯 Kotlin)-> 交互器(纯 Kotlin)-> 视图模型(安卓)-> 视图(安卓)

所以要清楚,view唯一知道的viewmodelviewmodel唯一知道的interactor。视图(通常是app模块)是MainActivity生活的地方。

我目前正在interactor隔离工作,我正在尝试使用 Dagger 2 进行注射。我在interactor模块中编写了以下代码:

... (Build.gradle)
implementation 'com.google.dagger:dagger:2.20'
kapt 'com.google.dagger:dagger-compiler:2.20'
...

abstract class ApiServiceInteractor() {
    @Inject lateinit var apiService: ApiService
    @Inject lateinit var schedulers: InteractorSchedulers
}

class Posts @Inject constructor() : ApiServiceInteractor() {
    fun fetch(): Single<List<PostSummary>> =
        apiService.getPosts()
            .subscribeOn(schedulers.io())
            .toObservable()
            .flatMapIterable { postList -> postList }
            .map { post -> PostSummary(post.id, post.title) }
            .toList()
}

@Module
open class InteractorModule {
    @Singleton @Provides 
    open fun provideApiService(): ApiService = ApiService.create()

    @Provides 
    open fun provideSchedulers(): InteractorSchedulers = InteractorSchedulers()
}

@Component
interface Component {
    fun inject(posts: Posts)
}

val dagger = DaggerComponent.create() // <--- not generated!!!

代码无法编译。编译器抱怨注入apiService并需要一个对应的schedulers,而且实现不是自动生成的。现在,我意识到这个界面在这里没有意义,但是您需要一个自动生成的界面,而这只是现阶段的原型设计。ApiServiceInteractor@ProvidesDaggerComponentComponentDaggerComponent

如果我将Component界面和移动DaggerComponent.create()到视图中(并使用注入签名MainActivity而不是帖子),那么一切都可以正常编译并被DaggerComponent创建。

我担心的是,当所有的东西都写完后,Dagger 将无法解决@ProvidesforapiService和,因为 the和 the (在哪里)schedulers之间存在一定程度的分离。我见过的唯一与此类似的示例在( ) 模块中。但是,如果我这样做,我将打破干净的代码架构依赖规则,因为它将依赖于.viewinteractor@Provides@Providesviewappviewinteractor

那么它会按原样工作吗?这些值会被注入吗?

更新

我从 中删除了 '@Component' 和 'DaggerComponent' 声明view,将它们放回原处interactor并添加了 '@Component(modules = [InteractorModule::class])'。编译器不再抱怨缺少提供(感谢 Ivan),但 IDE 仍然报告 DaggerComponent 不存在。在 Posts init 中调用DaggerComponent.create().inject(this)不会编译,因为 DaggerComponent 尚未生成。

所以看起来DaggerComponent只能在view模块中生成,这意味着@Component声明也必须在view模块中,以及modules = [InteractorModule::class]注释参数。一旦你这样做了,你就会在viewinteractoron之间产生依赖关系InteractorModule,从而打破了干净的代码架构依赖规则。

所以主要问题仍然存在,如何让 Dagger 2 在从 Android 层移除的纯 Kotlin 模块中工作?

标签: androidkotlindagger-2clean-architecture

解决方案


推荐阅读