我正在阅读一些代码,有困难理解
import dagger.Component
import dagger.Module
import dagger.Provides
import javax.inject.Inject
class Sound(val noise: String)
class Dog @Inject constructor(val sound: Sound)
@Module
class DogModule() {
@Provides
fun provideWoWo(): Sound = Sound("wowo")
@Provides
fun provideDog(sound : Sound): Dog = Dog(sound)
}
@Component(modules = [ DogModule::class ])
interface AnimalComponent {
val dog: Dog
}
fun main() {
val component = DaggerAnimalComponent.create()
println("The dog has sound ${component.dog.sound.noise}.")
}
为什么class Sound(val noise: String)
没有@Inject
?
我想会的class Sound @Inject constructor(val noise: String)
因为Sound
类实例也像Dog
类实例一样通过dagger创建
因为您显式地设置了@Provides
与构造函数参数。@Inject
用于省略@Provides
。在您的代码中,Dog
上的@Inject
也可以被删除。
总而言之——如果你用@Provides
创建这个类,你不必添加@Inject
因为Sound类实例也是通过dagger创建的,就像Dog类实例
这是不正确的:Dog
和Sound
都不是通过Dagger创建的。Dagger允许Dog
和Sound
被注入,但是在模块中,你是在你定义的@Provides
方法/函数中创建实例。
这也意味着Dog
和Sound
的@Inject
注释目前被忽略,因为Dagger不是这些对象的构造的一部分。相反,您可以自己提供这些:@Provides
方法和函数可以接收图中的对象,Dagger将提供这些对象,这就是您将Sound
作为@Provides Dog
方法的一部分接收的方式。因此,如果要更改Dog
的构造函数参数列表,则需要自己更改@Provides
方法。Dagger也不会自动填充@Inject
注释的方法和字段,在文档中标记为"方法注入";和"字段注入"。
如果你要删除Dog
的@Provides
方法,那么Dagger会自己读取参数列表,并在它改变时自动做出反应。方法和字段注入也会自动工作。
@Inject
构造函数的类上使用@Provides
。我建议尽可能使用@Inject
,并将@Provides
保留给您无法控制的代码或其他特殊情况。Android Dagger 2: Inject vs . providers