'How to @Inject an interface in @HiltViewModel?

I am trying to run the following pieces of code.

My ViewModel:

@HiltViewModel
class SplashModel @Inject constructor(private val preferenceRep: PreferenceRep) : ViewModel() {

    private val _intoEvent = EventLiveData<Unit>()
    val intoEvent = _intoEvent.asLiveData()

    private val _homeEvent = EventLiveData<Unit>()
    val homeEvent = _homeEvent.asLiveData()

    init {
        viewModelScope.launch(Dispatchers.IO) {
            val isFirstTime = preferenceRep.isFirstTime().awaitValueOrError()
            delay(800L)
            if (isFirstTime)
                _intoEvent post EventUnit
            else
                _homeEvent post EventUnit
        }
    }
}

My Fragment:

@AndroidEntryPoint
class SplashFragment : Fragment() {

    private val splashModel by viewModels<SplashModel>()

    private val binding get() = splash!!
    private var splash: FragmentSplashBinding? = null

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        splash = FragmentSplashBinding.inflate(inflater, container, false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        splashModel.intoEvent.observe(viewLifecycleOwner, EventObserver {
            navigate(R.id.nav_intro)
        })
        splashModel.homeEvent.observe(viewLifecycleOwner, EventObserver {
            navigate(R.id.nav_home)
        })
    }

    private fun navigate(id: Int) {
        findNavController().apply {
            popBackStack()
            navigate(id)
        }
    }

    override fun onDestroyView() {
        super.onDestroyView()
        splash = null
    }
}

My App class:

@HiltAndroidApp
class App : Application() {}

My Preference Repository:

interface PreferenceRep {
    fun isFirstTime(): FlowResult<Boolean>
}

My Impl of Preference:

class PreferenceRepImpl @Inject constructor(private val dao: PreferenceDao) : PreferenceRep {

    override fun isFirstTime(): FlowResult<Boolean> {
        return dao.isFirstTime()
            .map { SuccessResult(it) }
            .catch { ErrorResult(RepositoryException(it)) }
    }
}

My PreferenceDao:

interface PreferenceDao {
    fun isFirstTime(): Flow<Boolean>
}

My Module:

@Module
@InstallIn(SingletonComponent::class)
abstract class PreferenceModule {

    @Provides
    @Singleton
    abstract fun preferenceDao(daoImpl: PreferenceDaoImpl): PreferenceDao

}

My PreferenceDaoImpl:

class PreferenceDaoImpl @Inject constructor(@ApplicationContext private val context: Context) : PreferenceDao {

    private val preferences = PreferenceManager.getDefaultSharedPreferences(context)

    @ExperimentalCoroutinesApi
    private val flowPref = FlowSharedPreferences(preferences)

    override fun isFirstTime(): Flow<Boolean> {
        return flowPref.boolean(KEY_FIRST_TIME, true).asFlow()
    }

    companion object {
        private const val KEY_FIRST_TIME = "KEY_FIRST_TIME"
    }
}

And the exception:

error: [Dagger/MissingBinding] xxx.xxx.xxx.utils.preferences.PreferenceRep cannot be provided without an @Provides-annotated method.
  public abstract static class SingletonC implements App_GeneratedInjector,
                         ^
      xxx.xxx.xxx.utils.preferences.PreferenceRep is injected at
          xxx.xxx.xxx.utils.models.SplashModel(preferenceRep)
      xxx.xxx.xxx.utils.models.SplashModel is injected at
          xxx.xxx.xxx.utils.models.SplashModel_HiltModules.BindsModule.binds(arg0)
      @dagger.hilt.android.internal.lifecycle.HiltViewModelMap java.util.Map<java.lang.String,javax.inject.Provider<androidx.lifecycle.ViewModel>> is requested at
          dagger.hilt.android.internal.lifecycle.HiltViewModelFactory.ViewModelFactoriesEntryPoint.getHiltViewModelMap() [xxx.xxx.xxx.utils.App_HiltComponents.SingletonC ? xxx.xxx.xxx.utils.App_HiltComponents.ActivityRetainedC ? xxx.xxx.xxx.utils.App_HiltComponents.ViewModelC]

I searched for a solution, but did not find anything how to deal with annotations within the PreferenceRep interface. By the way I am trying to get it done like in this sample project: https://github.com/android/architecture-samples but using Dagger Hilt.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source