android - Dagger 2 会在从 Android 层移除的纯 Kotlin 模块中工作吗?
问题描述
我正在尝试实现类似于此处描述的干净代码架构。为了强制执行它,每一层都是 Android Studio 中的一个独立模块,具有依赖链,因此:
模型(纯 Kotlin)-> 交互器(纯 Kotlin)-> 视图模型(安卓)-> 视图(安卓)
所以要清楚,view
唯一知道的viewmodel
和viewmodel
唯一知道的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
@Provides
DaggerComponent
Component
DaggerComponent
如果我将Component
界面和移动DaggerComponent.create()
到视图中(并使用注入签名MainActivity
而不是帖子),那么一切都可以正常编译并被DaggerComponent
创建。
我担心的是,当所有的东西都写完后,Dagger 将无法解决@Provides
forapiService
和,因为 the和 the (在哪里)schedulers
之间存在一定程度的分离。我见过的唯一与此类似的示例在( ) 模块中。但是,如果我这样做,我将打破干净的代码架构依赖规则,因为它将依赖于.view
interactor
@Provides
@Provides
view
app
view
interactor
那么它会按原样工作吗?这些值会被注入吗?
更新
我从 中删除了 '@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]
注释参数。一旦你这样做了,你就会在view
和interactor
on之间产生依赖关系InteractorModule
,从而打破了干净的代码架构依赖规则。
所以主要问题仍然存在,如何让 Dagger 2 在从 Android 层移除的纯 Kotlin 模块中工作?
解决方案
推荐阅读
- json - JSONConverter 的 Kafka Connect 模式格式
- javascript - Onclick 函数返回引用错误
- sql-server - 数据库版本号位置
- hive - Hadoop Hive SQL 从具有保留关键字名称的表中提取数据
- amazon-web-services - AWS SSO 应用程序中的属性映射如何与 Azure 用户名一起使用?
- microsoft-dynamics - Ribbon Workbench显示规则-bool值应该如何使用?
- html - 导航中的背景边框问题
- c++ - 如何在 C++ 中测量高分辨率按键时间?
- python - 尝试在 32 位 Linux Mint 上编译 Bazel 时出现 InvalidProtocolBufferException
- c# - 在 C# 中构建序列化程序的最有效方法