我使用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的代码的情况下提供这样的依赖?
答案 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>()
}
}
您的子组件构建器因此绑定SomeActivity
和Activity
,并且您的子组件包含BaseActivityModule
以及上面定义的绑定。
有关详细信息,您还可以查看this related question并执行更多步骤...