我无法提供带匕首的视图模型
I can't provide a viewmodel with dagger
Dagger 给我以下错误:
[Dagger/MissingBinding] java.util.Map<java.lang.Class<? extends androidx.lifecycle.ViewModel>,javax.inject.Provider<androidx.lifecycle.ViewModel>> cannot be provided without an @Provides-annotated method.
匕首版本:
def dagger_version = "2.28"
implementation "com.google.dagger:dagger:$dagger_version"
kapt "com.google.dagger:dagger-compiler:$dagger_version"
科特林版本:
kotlin_version = '1.3.50'
gradle版本
classpath 'com.android.tools.build:gradle:3.5.0'
我已经尝试在 (app)build.gradle
文件中插入 kapt { correctErrorTypes = true}
。
我的代码:
@Singleton
@Component(modules = [DataModule::class, ViewModelBuilderModule::class, SubcomponentsModule::class])
interface ApplicationComponent {
@Component.Factory
interface Factory {
fun create(@BindsInstance applicationContext: Context): ApplicationComponent
}
fun mainComponent(): MainComponent.Factory
}
@Module(subcomponents = [MainComponent::class])
object SubcomponentsModule
和
@Module
interface MainModule {
@Binds
@IntoMap
@ViewModelKey(SearchViewModel::class)
abstract fun bindSearchViewModel(searchViewModel: SearchViewModel): ViewModel
}
和
class TodoViewModelFactory @Inject constructor(
private val creators: @JvmSuppressWildcards 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 {
@Suppress("UNCHECKED_CAST")
return creator.get() as T
} catch (e: Exception) {
throw RuntimeException(e)
}
}
}
@Module
abstract class ViewModelBuilderModule {
@Binds
abstract fun bindViewModelFactory(factory: TodoViewModelFactory): ViewModelProvider.Factory
}
@Target(
AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER
)
@Retention(AnnotationRetention.RUNTIME)
@MapKey
annotation class ViewModelKey(val value: KClass<out ViewModel>)
日志:
error: [Dagger/MissingBinding] java.util.Map<java.lang.Class<? extends androidx.lifecycle.ViewModel>,javax.inject.Provider<androidx.lifecycle.ViewModel>> cannot be provided without an @Provides-annotated method.
public abstract interface ApplicationComponent {
^
java.util.Map<java.lang.Class<? extends androidx.lifecycle.ViewModel>,javax.inject.Provider<androidx.lifecycle.ViewModel>> is injected at
com.movies.allmovies.di.TodoViewModelFactory(creators)
com.movies.allmovies.di.TodoViewModelFactory is injected at
com.movies.allmovies.di.ViewModelBuilderModule.bindViewModelFactory(factory)
androidx.lifecycle.ViewModelProvider.Factory is injected at
com.movies.allmovies.ui.search.SearchFragment.viewModelFactory
com.movies.allmovies.ui.search.SearchFragment is injected at
com.movies.allmovies.di_subcomponent.MainComponent.inject(com.movies.allmovies.ui.search.SearchFragment) [com.movies.allmovies.di.ApplicationComponent ? com.movies.allmovies.di_subcomponent.MainComponent]
正如 IR42 在评论中指出的那样,将 MainModule::class
添加到 ApplicationComponent modules
解决了问题。
Dagger 给我以下错误:
[Dagger/MissingBinding] java.util.Map<java.lang.Class<? extends androidx.lifecycle.ViewModel>,javax.inject.Provider<androidx.lifecycle.ViewModel>> cannot be provided without an @Provides-annotated method.
匕首版本:
def dagger_version = "2.28"
implementation "com.google.dagger:dagger:$dagger_version"
kapt "com.google.dagger:dagger-compiler:$dagger_version"
科特林版本:
kotlin_version = '1.3.50'
gradle版本
classpath 'com.android.tools.build:gradle:3.5.0'
我已经尝试在 (app)build.gradle
文件中插入 kapt { correctErrorTypes = true}
。
我的代码:
@Singleton
@Component(modules = [DataModule::class, ViewModelBuilderModule::class, SubcomponentsModule::class])
interface ApplicationComponent {
@Component.Factory
interface Factory {
fun create(@BindsInstance applicationContext: Context): ApplicationComponent
}
fun mainComponent(): MainComponent.Factory
}
@Module(subcomponents = [MainComponent::class])
object SubcomponentsModule
和
@Module
interface MainModule {
@Binds
@IntoMap
@ViewModelKey(SearchViewModel::class)
abstract fun bindSearchViewModel(searchViewModel: SearchViewModel): ViewModel
}
和
class TodoViewModelFactory @Inject constructor(
private val creators: @JvmSuppressWildcards 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 {
@Suppress("UNCHECKED_CAST")
return creator.get() as T
} catch (e: Exception) {
throw RuntimeException(e)
}
}
}
@Module
abstract class ViewModelBuilderModule {
@Binds
abstract fun bindViewModelFactory(factory: TodoViewModelFactory): ViewModelProvider.Factory
}
@Target(
AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER
)
@Retention(AnnotationRetention.RUNTIME)
@MapKey
annotation class ViewModelKey(val value: KClass<out ViewModel>)
日志:
error: [Dagger/MissingBinding] java.util.Map<java.lang.Class<? extends androidx.lifecycle.ViewModel>,javax.inject.Provider<androidx.lifecycle.ViewModel>> cannot be provided without an @Provides-annotated method.
public abstract interface ApplicationComponent {
^
java.util.Map<java.lang.Class<? extends androidx.lifecycle.ViewModel>,javax.inject.Provider<androidx.lifecycle.ViewModel>> is injected at
com.movies.allmovies.di.TodoViewModelFactory(creators)
com.movies.allmovies.di.TodoViewModelFactory is injected at
com.movies.allmovies.di.ViewModelBuilderModule.bindViewModelFactory(factory)
androidx.lifecycle.ViewModelProvider.Factory is injected at
com.movies.allmovies.ui.search.SearchFragment.viewModelFactory
com.movies.allmovies.ui.search.SearchFragment is injected at
com.movies.allmovies.di_subcomponent.MainComponent.inject(com.movies.allmovies.ui.search.SearchFragment) [com.movies.allmovies.di.ApplicationComponent ? com.movies.allmovies.di_subcomponent.MainComponent]
正如 IR42 在评论中指出的那样,将 MainModule::class
添加到 ApplicationComponent modules
解决了问题。