Sunday, 27 June 2021

Hilt field injection in the super Fragment or ViewModel

I'm using Dagger-Hilt for dependency injection in my Android project, now I have this situation where I have a base abstract Fragment

BaseFragment.kt

abstract class BaseViewModel constructor(
    val api: FakeApi,
) : ViewModel() {
    
    //...
    
}

Here, I have a dependency which is FakeApi. What I'm trying to do is to inject the FakeApi into the BaseViewModel to be available in the BaseViewModel and all its children.

  • The first approach I tried is using the constructor injection and inject it to the child and pass it to the super using the constructor.

TaskViewModel.kt

@HiltViewModel
class TaskViewModel @Inject constructor(
    api: FakeApi
) : BaseViewModel(api){

}

This approach works fine, but I don't need to pass the dependency from the child to the super class, I need the FakeApi to be automatically injected in the BaseViewModel without having to pass it as I have three levels of abstraction (There is another class inheriting from the TaskViewModel) So I have to pass it two times.

  • The second approach was to use the field injection as follows

BaseViewModel.kt

abstract class BaseViewModel: ViewModel() {
    @Inject
    lateinit var api: FakeApi
    //...
}

TaskViewModel.kt

@HiltViewModel
class TaskViewModel @Inject constructor(): BaseViewModel() {
    
}

This approach didn't work for me and the FakeApi wasn't injected and I've got an Exception

kotlin.UninitializedPropertyAccessException: lateinit property api has not been initialized

My questions are

  • Why field injection doesn't work for me?
  • Is there any way to use constructor injection for the super class instead of passing the dependency from the child?


from Hilt field injection in the super Fragment or ViewModel

No comments:

Post a Comment