Kotlin + Dagger - 为 ViewModel 工厂注入 Map [英] Kotlin + Dagger - inject Map for ViewModel factory
问题描述
我将新的架构组件与 Dagger2 一起使用,并且我想使用 Factory 类注入我的 ViewModel.Factory 类本身是可注入的.当 Factory 类在 Java 中定义时,这一切都很好,但是当我将它转换为 Kotlin 时,Dagger2 不知道如何为构造函数生成 Map,而在 Java 中它知道如何这样做.我认为不同之处在于,在转换之后,Factory 类使用来自 kotlin 包的 Map,而不是来自 java.util.Map 包的 Map.如何让 Dagger2 为 Factory 构造函数生成地图?
I'm using the new Architecture Components with Dagger2 and I would like to inject my ViewModels using a Factory class. The Factory class is itself injectable. This all works well when the Factory class is defined in Java, but when I convert it to Kotlin, Dagger2 does not know how to generate the Map for the constructor, while in Java it knows how to do so. I presume the difference is that, after conversion, the Factory class uses the Map from the kotlin package, as opposed to from java.util.Map package. How can I get Dagger2 to generate the map for the Factory constructor?
这是工厂类
@ActivityScope
class MainActivityViewModelFactory @Inject
constructor(private val creators: Map<Class<out ViewModel>, Provider<ViewModel>>) : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
var creator: Provider<out ViewModel>? = creators[modelClass]
if (creator == null) {
for ((key, value) in creators) {
if (modelClass.isAssignableFrom(key)) {
creator = value
break
}
}
}
if (creator == null) {
throw IllegalArgumentException("unknown model class " + modelClass)
}
try {
return creator.get() as T
} catch (e: Exception) {
throw RuntimeException(e)
}
}
}
这是错误
Error:java.util.Map<java.lang.Class<? extends android.arch.lifecycle.ViewModel>,? extends javax.inject.Provider<android.arch.lifecycle.ViewModel>> cannot be provided without an @Provides-annotated method.
我尝试创建一个模块来提供地图,但没有帮助.
I tried creating a module to provide the map, but that didn't help.
@ActivityScope
@Module
class MapModule {
@Provides
fun provideMap(): Map<Class<out ViewModel>, Provider<ViewModel>> = mutableMapOf()
}
推荐答案
我稍微修改了你的 ViewModelFactory
代码:
I modified your ViewModelFactory
code a bit:
@ActivityScope
class MainActivityViewModelFactory @Inject
constructor(private val creators: Map<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>>) : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
var creator: Provider<out ViewModel>? = creators[modelClass]
if (creator == null) {
for ((key, value) in creators) {
if (modelClass.isAssignableFrom(key)) {
creator = value
break
}
}
}
if (creator == null) {
throw IllegalArgumentException("unknown model class " + modelClass)
}
try {
return creator.get() as T
} catch (e: Exception) {
throw RuntimeException(e)
}
}
}
你可以试试这个吗?我添加了 @JvmSuppressWildcards
注释.
Can you try with this?
I added @JvmSuppressWildcards
annotation.
有关更多信息,您可以查看:https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.jvm/-jvm-suppress-wildcards/index.html
For more information you can check: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.jvm/-jvm-suppress-wildcards/index.html
你可以从我的 repo 中找到现场演示:https://github.com/savepopulation/dc-tracker一个>
You can find a live demo from my repo: https://github.com/savepopulation/dc-tracker
这篇关于Kotlin + Dagger - 为 ViewModel 工厂注入 Map的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!