简体   繁体   English

ViewModel 中的 Kotliin Dagger 字段注入引发 Dagger/Binding 异常

[英]Kotliin Dagger Field Injection in ViewModel Throws Dagger/Binding Exception

I have followed this tutorial in order to do DI in my viewmodels.我遵循本教程是为了在我的视图模型中进行 DI。 But I currently am stuck.但我目前被卡住了。

I have created a ViewModelFactory for my viewmodel which is as follows:我为我的视图模型创建了一个 ViewModelFactory,如下所示:

class HomeViewModelFactory @Inject constructor(
    private val creators: Map<Class<out ViewModel>,
            Provider<ViewModel>>
): ViewModelProvider.Factory{

    override fun <T : ViewModel?> create(modelClass: Class<T>): T {
        return creators[modelClass]?.get() as T
    }
}

Followed by a ViewModel:后跟一个 ViewModel:

class HomeViewModel @Inject constructor(private val songsRepository: SongsRepository): ViewModel()

For DI I have created two components.对于 DI,我创建了两个组件。 One is my main application component, the other is a component which depends on the main application.一个是我的主应用程序组件,另一个是依赖于主应用程序的组件。

@Singleton
@Component(modules = [AppModule::class])
public interface AppComponent {
    fun songRepository(): SongsRepository
    fun libraryManager(): LibraryManager
    fun inject(mainActivity: MainActivity)
}


@Module
public class AppModule(val application: Application){

    @Provides @Singleton
    fun providesApplication(): Application{
        return application
    }

    @Provides @Singleton
    fun providesLibraryManager(): LibraryManager {
        return LibraryManager(application)
    }

    @Provides @Singleton
    fun providesSongRepository(libraryManager: LibraryManager): SongsRepository {
        return SongsRepository(libraryManager)
    }
}

And my ViewModelModule is as follows:我的 ViewModelModule 如下:

@Module
public class ViewModelModule {

    @Target(AnnotationTarget.FUNCTION)
    @Retention(AnnotationRetention.RUNTIME)
    @MapKey
    internal annotation class ViewModelKey(val value: KClass<out ViewModel>)

    @AppScope
    @Provides
    fun providesHomeViewModelFactory(providerMap: Map<Class<out ViewModel>, Provider<ViewModel>>): HomeViewModelFactory {
        return HomeViewModelFactory(providerMap)
    }

    @AppScope
    @IntoMap
    @Provides
    @ViewModelKey(HomeViewModel::class)
    fun providesHomeViewModel(songsRepository: SongsRepository): HomeViewModel{
        return HomeViewModel(songsRepository)
    }
}

@AppScope
@Component(modules = [ViewModelModule::class], dependencies = [AppComponent::class])
public interface ViewModelComponent {
    fun homeViewModelFactory(): HomeViewModelFactory
    fun homeViewModel(): HomeViewModel
    fun inject(homeFragment: HomeFragment)
}

The error I'm getting is this:我得到的错误是这样的:

error: [Dagger/MissingBinding] java.util.Map,?错误:[Dagger/MissingBinding] java.util.Map,? extends javax.inject.Provider> cannot be provided without an @Provides-annotated method.如果没有 @Provides 注释方法,则无法提供 extends javax.inject.Provider>。

I seriously don't have any idea why is this happening since all my classes have @Inject constructors.我真的不知道为什么会发生这种情况,因为我所有的类都有 @Inject 构造函数。 Dagger's documentation is not helping me either. Dagger 的文档也没有帮助我。 I would be grateful if you could advise me on this matter.如果您能就此事向我提出建议,我将不胜感激。

The error message indicates that the following code is wrong:错误信息表明以下代码错误:

fun providesHomeViewModelFactory(providerMap: Map<Class<out ViewModel>, Provider<ViewModel>>): HomeViewModelFactory {
    return HomeViewModelFactory(providerMap)
}

It should be它应该是

fun providesHomeViewModelFactory(providerMap: Map<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>>): HomeViewModelFactory {
    return HomeViewModelFactory(providerMap)
}

It is because the signature of Map interface is Map<K, out V> , that means the Map<..., Provider<ViewModel>> will be compiled to Map<..., ? extends Provider<ViewModel>>因为Map接口的签名是Map<K, out V> ,也就是说Map<..., Provider<ViewModel>>会被编译成Map<..., ? extends Provider<ViewModel>> Map<..., ? extends Provider<ViewModel>> Java code, so you are asking dagger for latter one but it only has former one in its object graph, then the compiler throws you the error. Map<..., ? extends Provider<ViewModel>> Java 代码,因此您要求 dagger 获取后一个,但它的对象图中只有前一个,然后编译器会向您抛出错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM