目录
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
dagger与抽象
继承、封装和多态是面向对象的三大特征,这三大特征无一不是围绕着抽象这个词展开的,但在前几篇的例子中,我们的依赖都是具体的类型,比如Computer
、CPU
、Memory
,严重违反了依赖倒置原则:
模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系是通过接口或抽象类产生的
总之,我们接下来需要加上抽象的思想,看看dagger怎样处理
新增需求
现在我们将Computer
改为一个抽象类,并且派生出两个子类:WindowsComputer
和LinuxComputer
,而Activity
中需要依赖这两种Computer
,并显示它们的信息,改动如下:
// 将Computer改为抽象类
abstract class Computer(private val os: String, private val price: Int) {
@set:Inject lateinit var cpu: CPU
@set:Inject lateinit var memory: Memory
init {
// 通常在非final类的构造函数中应避免传递this、调用非final方法等,因为父类构造函数先于子类执行,此时调用一些被子类重写的方法可能产生错误。不过这里是对父类中的依赖进行注入,所以Suppress了
@Suppress("LeakingThis")
DaggerComputerComponent
.builder()
.memoryModule(MemoryModule(8192))
.build()
.inject(this)
}
fun execute(builder: StringBuilder) {
// CPU执行时除了返回自身信息,还要将CPU和Memory的信息一并返回
builder.append("Computer OS: ").append(os).append("\n")
builder.append("Computer Price: ").append(price).append("\n")
cpu.execute(builder)
memory.execute(builder)
}
}
// 写好两个派生类
class WindowsComputer(price: Int) : Computer("Windows", price)
class LinuxComputer(price: Int