目录
0. 前言
1. 依赖与注入
2. @Inject
3. @Module & @Provides
4. @Component
5. @Qualifier
6. Provider & Lazy
7. @Scope
8. 注入到Set和Map容器
9. Bind系列注解
10. dagger中依赖关系与继承关系
11. dagger.android
目的
通过前面几篇文章,我们了解到@Module
代表着一个数据仓库,提供需要注入的依赖实例;而@Component
代表着一个桥接类,桥接了被注入对象和其依赖的注入器/工厂类。打开这两个注解的源码,会发现原来还有新的世界等待着我们去探索:@Module.includes
、@Module.subcomponents
、@Component.dependencies
,这些就是本系列压轴中要介绍的内容了
@Module.includes
从此注解的名字就不难猜出它是干什么的了,这里我们假设蓝牙(BlueTooth
)模块对于Computer
来说也属于一种外设(Device
):
@Module(includes = [BlueToothModule::class]) // 表明DeviceModule数据仓库含有BlueToothModule数据仓库,也能够提供BlueTooth实例
class DeviceModule {
/* ... */ }
@Component(modules = [/* ... */DeviceModule::class /*, BlueToothModule::class */]) // 在ComputerComponent中,就可以仅依赖DeviceModule而不必再声明对BlueToothModule的依赖了
interface ComputerComponent {
代码上看起来更直观了,@Module.includes
就是实现了Module
的一种组合关系
@Component.dependencies
我们在Activity
中会通过Toast显示应用名,当时是这样写的:
val name = (applicationContext as LearnDaggerApplication).component.getAppName()
Component
作为桥接类,不仅能够提供注入的接口(inject()
方法),还能直接提供依赖实例(比如上面的getAppName()
),那么一个Component
需要用到另一个Component
提供的依赖,就可以用@Component.dependencies
:
// 没有改动ApplicationComponent,这里只是贴出来示例
@ApplicationScope
@Component(modules = [ApplicationModule::class])
interface ApplicationComponent {
@ApplicationModule.ApplicationName fun getAppName(): String
}
@MonitorScope
@Component(
modules = [ComputerModule::class, TimestampModule::class, MonitorModule::class, AMDCPUModule::class],
dependencies = [ApplicationComponent::class] // 添加Component依赖
)
interface CaseActivityComponent {
/* ... */
@ApplicationModule.ApplicationName fun getAppName(): String // 添加了Component依赖后,这个Component也有提供应用名这个依赖的能力了
@Component.Builder
interface Builder {
/* ... */
fun applicationComponent(component: ApplicationComponent): Builder // 别忘了自定义Builder需要为每一个dependencies提供方法
}
}
// 最后修改一下Activity中的使用逻辑
override fun onCreate(savedInstanceState: Bundle?) {
/* ... */
component = DaggerCaseActivityComponent
.builder()
.computerModule(ComputerModule(6666,