I am having a problem that I need inject an instance of repository class into Application class which is provided by Module (Installed in ViewModelComponent, and provide function marked with @ViewModelScope annotation)
Repository
interface IARepository
class ARepository @Inject constructor() : IARepository
Module
@Module
@InstallIn(ViewModelComponent::class)
interface RepositoryModule {
@Binds
@ViewModelScoped
fun provideARepos(impl: ARepository): IARepository
}
ViewModel
@HiltViewModel
class TestViewModel @Inject constructor(
private val useCase1: UseCase1,
private val useCase2: UseCase2,
) {
...
}
Two UseCase1
and UseCase2
are using IARepository
, since if I provides IARepository
with ViewModelScope, two instance useCase1
and useCase2
will be using the same instance of repository.
It worked until I inject repository into Application (singleton things)
Application
@HiltAndroidApp
class TestApplication : Application() {
@Inject
lateinit var a: IARepository
}
After that I got error
[Dagger/MissingBinding] IARepository cannot be provided without an @Provides-annotated method.
public abstract static class SingletonC implements FragmentGetContextFix.FragmentGetContextFixEntryPoint
Application_HiltComponents.java:129: error: [Dagger/MissingBinding] ...core.domain.IARepository cannot be provided without an @Provides-annotated method.
public abstract static class SingletonC implements FragmentGetContextFix.FragmentGetContextFixEntryPoint,
^
A binding for ....core.domain.IARepository exists in ...Application_HiltComponents.ViewModelC:
....core.domain.IARepository is injected at
[...Application_HiltComponents.SingletonC] ...Application.a
...Application is injected at
...Application_HiltComponents.SingletonC] ...Application_GeneratedInjector.injectMoonRoverApplication
In application, I tried switch to inject directly implementation class is ARepository
, it worked fine.
@HiltAndroidApp
class TestApplication : Application() {
@Inject
lateinit var a: ARepository
}
But I still want to use interface. Are there any solution for it?
CodePudding user response:
I think you have to use @Provides in module as below
@Module
@InstallIn(ViewModelComponent::class)
interface RepositoryModule {
@Binds
@ViewModelScoped
@Provides
fun provideARepos(impl: ARepository): IARepository
}
Also add @HiltViewModel in your view model as below
@HiltViewModel
class TestViewModel @Inject constructor(
private val useCase1: UseCase1, private val useCase2: UseCase2
) {
...
}
I hope it will help you.
CodePudding user response:
in viewmodel please specify the @HiltViewModel
@HiltViewModel
class TestViewModel @Inject constructor(
private val useCase1: UseCase1, private val useCase2: UseCase2
) {
...
}
edited:-
@Module
@InstallIn(SingletonComponent::class)
object Module {
@Provides
fun ProvideImplRepo() = ImplRepo()
}
@Module
@InstallIn(ViewModelComponent::class)
abstract class RepositoryModule {
@Binds
abstract fun bindLoginRepository(impl: ImplRepo): Repo
}