Dagger-android共享活动之间的依赖关系

时间:2018-05-16 20:34:22

标签: android kotlin dagger-2 dagger

我使用dagger-android进行DI。我希望为每个活动提供一些常见的依赖关系。它们依赖于Activity类,但不会在某个Activity实现上进行中继。像这样:

class NavigatorImpl(private val activity: Activity) : Navigator {..}

现在我必须在每个ActivityModule上编写相同的代码:

@Module
class SomeActivityModule {

    @Provides
    fun navigator(activity: SomeActivity): Navigator = NavigatorImpl(activity)

    // some deps...

}

@Module
class AnotherActivityModule {

    @Provides
    fun navigator(activity: AnotherActivity): Navigator = NavigatorImpl(activity)

    // another deps...

}

我尝试通过AndroidSupportInjectionModule提供这些依赖项,但事实证明Dagger为每个Activity生成单独的子模块,我们只能在某些模块(SomeActivityModule和{{}访问Activity依赖项。 1}}在这个例子中):

AnotherActivityModule

那么如何在不重复每个ActivityModule的代码的情况下提供这样的依赖?

1 个答案:

答案 0 :(得分:2)

首先,您将所有常用内容放入可以重复使用的模块中。 (另请使用@Binds构造函数注入,如下所示

class Navigator @Inject constructor(activity : Activity) { /* ... */ }

@Module
interface BaseActivityModule {

    @Binds
    fun navigator(navigator: NavigatorImpl): Navigator

    // other bindings...

}

然后您必须切换到自定义子组件声明而不是@ContributesAndroidInjector。有一个related open issue,但是现在你必须编写样板文件。

您声明AndroidInjector.Factory绑定了您需要的所有内容,然后将其用于子组件构建器而不是默认的AndroidInjector.Builder

object MyCustomInjector {

  abstract class ActivityBuilder<T : Activity> : AndroidInjector.Factory<T> {
    override fun create(instance: T): AndroidInjector<T> {
      seedInstance(instance)
      activity(instance)
      return build()
    }

    @BindsInstance
    abstract fun seedInstance(instance: T)

    @BindsInstance
    abstract fun activity(instance: Activity)

    abstract fun build(): AndroidInjector<T>
  }
}

@Module(subcomponents = [(SomeActivityModule.SomeActivitySubcomponent::class)])
abstract class SomeActivityModule {

  @Binds
  @IntoMap
  @ActivityKey(SomeActivity::class)
  internal abstract fun contributeSomeActivity(builder: SomeActivitySubcomponent.Builder): AndroidInjector.Factory<out Activity>

  @PerActivity
  @Subcomponent(modules = [BaseActivityModule::class])
  interface SomeActivityActivitySubcomponent : AndroidInjector<SomeActivity> {
    @Subcomponent.Builder
    abstract class Builder : MyCustomInjector.ActivityBuilder<SomeActivity>()
  }
}

您的子组件构建器因此绑定SomeActivityActivity,并且您的子组件包含BaseActivityModule以及上面定义的绑定。

有关详细信息,您还可以查看this related question并执行更多步骤...