android - 带有自定义限定符的 Dagger 多重绑定
问题描述
我调用了以下接口,该接口SettingHandler
负责处理与 Android 应用程序中的特定设置相关的事件。
interface SettingHandler {
fun onHandleEvent(event: SettingEvent)
fun candleHandleEvent(event: SettingEvent): Boolean
fun getSettingId(): SettingId
}
然后假设我有以下 Dagger 模块:
@Module
object SettingsModule {
@Provides
fun provideSettingPresenter(
view: SettingsContract.View,
settingHandlers: Set<@JvmSuppressWildcards SettingHandler>
): SettingsPresenter {
//
}
@Provides
@IntoSet
fun provideSettingHandlerA(
dependencyA: A,
dependencyB: B
): SettingHandler {
//
}
@Provides
@IntoSet
fun provideSettingHandlerB(
settingHandlerC: Provider<SettingHandler>
): SettingHandler {
//
}
@Provides
@IntoSet
fun provideSettingHandlerC(
settingHandlerB: Provider<SettingHandler>
): SettingHandler {
//
}
}
如您所见,这里没有什么特别之处,只需要使用SettingHandlerB
和SettingHandlerC
provider 方法即可。它们都相互依赖,所以我决定使用 Dagger 提供的 Provider 类来解决这种循环依赖。由于我需要一个设置处理程序的具体实现(用于SettingHandlerC
和SettingHandlerB
),我现在需要区分它们。这就是注释发挥作用的地方。我创建了以下限定符注释来区分不同的实现。SettingHandlerB
SettingHandlerC
@Qualifier
@Qualifier
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FIELD, AnnotationTarget.FUNCTION, AnnotationTarget.VALUE_PARAMETER)
annotation class SettingHandlerType(val id: SettingId)
SettingId
基本上是一个包含所有可能设置常量的枚举。所以现在我SettingHandler
的 s 模块如下所示:
@Module
object SettingsModule {
@Provides
fun provideSettingPresenter(
view: SettingsContract.View,
settingHandlers: Set<@JvmSuppressWildcards SettingHandler>
): SettingsPresenter {
//
}
@Provides
@SettingHandlerType(SettingId.A)
fun provideSettingHandlerA(
dependencyA: A,
dependencyB: B
): SettingHandler {
//
}
@Provides
@SettingHandlerType(SettingId.B)
fun provideSettingHandlerB(
@SettingHandlerType(SettingId.C)
settingHandlerC: Provider<SettingHandler>
): SettingHandler {
//
}
@Provides
@SettingHandlerType(SettingId.C)
fun provideSettingHandlerC(
@SettingHandlerType(SettingId.B)
settingHandlerB: Provider<SettingHandler>
): SettingHandler {
//
}
}
问题来了。多重绑定现在不起作用,因为我的所有SettingHandler
s 都带有@SettingHandlerType
注释,并且我注入的 SetSettingsPresenter
也需要注释。但是,使用例如注释@SettingHandlerType(SettingId.A)
将不起作用,因为在这种情况下, Set 将仅包含具有该特定限定符的设置处理程序(SettingHandlerA
在本例中为 )。我如何使用多重绑定构造一个 Set 数据结构,因为我真的不想提供另一个提供者方法来自己构造它?
任何帮助将非常感激。提前致谢。
解决方案
您需要两种不同类型的数据: type 的单个处理程序@SettingHandlerType(/*...*/) SettingHandler
和一组 type Set<SettingHandler>
。我认为最好的方法是让每个定义都带有一个@Binds @IntoSet
补充。
@Binds @IntoSet abstract fun bindSettingHandlerA(
@SettingHandlerType(SettingId.A) handler: SettingHandler): SettingHandler
不幸的是,由于您已在 Kotlin 中将其定义为 an ,因此将必然方法放在同一个对象上object
会稍微复杂一些。abstract
@Binds
您可能需要采用其他解决方案之一以使该拓扑适用于您的案例,包括使用 acompanion object
来捕获 else-static
@Provides
方法:
推荐阅读
- reactjs - React Hooks and Enzyme:React 一直告诉我将状态更新包装在 act(...) 中,即使我认为我做到了
- node.js - PureScript Node.FS.Sync readTextFile 返回垃圾
- reactjs - React apollo:访问缓存以了解分页查询了多少项
- reactjs - ReactHooks:存储值更改时调用回调
- javascript - 完整日历未在 Bootstrap 选项卡中自动加载?
- spring - 使用 Spring 的依赖于配置文件的 log4j2 配置
- asp.net-mvc - 有没有办法在 ASP.NET MVC 应用程序的组合框中选择空值?
- c# - 有没有办法将模型的数据作为 Razor 中的变量访问(而不是 Html.DisplayFor())?
- java - 如何将宽空间变为单个空间?Java 字符串
- git - 将分叉的存储库转回分支