我正在使用Kotlin和Dagger 2开发一个Android项目。我有一个MyModule
,其中定义了一些提供程序功能。
@Module
object MyModule {
@Provides
@JvmStatic
internal fun provideSomething(): Something {
...
}
}
在我的Foo
类中,我将Something
注入为成员变量:
class Foo(@Inject val something: Something) {
}
但是现在我想让这个Foo
类也可以注入到另一个类中,例如在名为Bar
的类中:
class Bar(@Inject val foo: Foo)
如何实现?如果使用Java,我可以做到:
class Foo {
// I inject something
@Inject
private Something something;
// I also make Foo to be injectable to other class
@Inject
public Foo()
}
但是如何在我的Kotlin Foo
课程中实现同样的目标?
答案 0 :(得分:1)
假设Something
是由您创建的类。您甚至不需要@Module
来提供它。
您可以这样做
class Something @Inject constructor() {
}
只需将@Inject添加到Something
构造函数中即可, Dagger 知道如何提供它。然后在您的Foo
类中
class Foo @Inject constructor() {
@Inject
lateinit var something: Something
}
完成,如果您拥有Something
类,则不需要@Module和@Component。
但是
如果Something
类不受您的控制,那么我们需要走很长的路,例如,
第1步:创建模块
@Module
object MyModule {
@Provides
@JvmStatic
internal fun provideSomething(): Something {
...
}
}
第2步:定义组件
@Component(modules = [MyModule::class])
interface MyComponent {
fun inject(foo: Foo) //mention the place where you need to inject variables
}
第3步:启动组件
class Foo @Inject constructor(){
@Inject
lateinit var something:Something
init{
DaggerMyComponent().create().inject(this) //do this before using `something` or else face `UninitializedPropertyException`
//You can now freely use `something`, **Dagger** has already performed his magic
}
}
更新:
假设Something
有一个参数化的构造函数,看起来像这样,
class Something @Inject constructor(mRandom : RandomClass)
,再次出现两种可能性
如果RandomClass
由您拥有,则可以将@Inject像这样添加到此RandomClass
构造函数中,
class RandomClass @Inject constructor(){
}
就是这样,匕首将在需要的地方提供RandomClass
。
如果RandomClass
不在您的控制之下,则需要使用@Module
这样提供它,
@Module
object RandomModule {
@JvmStatic
@Provides
fun providesRandomClass(): RandomClass {
...
}
}
将此@Module
添加到您的@Component
并在需要依赖项的任何地方启动@Component
(上面的步骤中已经提供了示例)。
故事的寓意是一种或另一种匕首应该知道如何提供 RandomClass
对于您的特定示例,假设我们有
class Something @Inject constructor(mString:String,customType:CustomType){
}
只需告诉 Dagger 如何提供String
和CustomType
@Module
object CustomModule {
@JvmStatic
@Provides
@Named("AnyName") //Just to differentiate which string we need
fun providesString() = "AnyName"
@JvmStatic
@Provides
fun providesCustomType(): CustomType {
...
}
}
,然后是对Something
构造函数的最后一点修改,
class Something @Inject constructor( @Named("AnyName") mString:String, customType:CustomType ){
}
答案 1 :(得分:0)
在kotlin中,您必须这样做:
class Foo @Inject constructor(val something: Something) {
}
我不确定您是否也可以使用相同的名称。