匕首2:让我的Foo班级可以注入Kotlin的其他班级

时间:2019-12-27 13:44:10

标签: android kotlin dagger-2

我正在使用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课程中实现同样的目标?

2 个答案:

答案 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 如何提供StringCustomType

@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) {
}

我不确定您是否也可以使用相同的名称。