Home > OS >  Inject an instance of repository class into Application class which is provided by Module with ViewM
Inject an instance of repository class into Application class which is provided by Module with ViewM

Time:02-06

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
}
  • Related