Dagger2 - Field injecting a variable in ViewModel. Is it problematic?

27 Views Asked by At

I learned dagger2 recently and came across a situation where I have to inject a variable of a class in my viewmodel. Almost everywhere, its recommended to pass that variable through ViewModelFactory and inject the variable in ViewModel Factory constructor. But, technically, I can also inject a field inside viewmodel and call component.init method in init() function of viewmodel. and I will still get the variable to use in my viewmodel without creating viewmodel factory. Is there any problem with this approach?

For eg My ViewModel

class MainActivityViewModel() : ViewModel() {

    @Inject
    lateinit var repository: MyRepository
    
    init {
        App.appComponent.inject(this)
    }
}
1

There are 1 best solutions below

0
Philio On

In general, you should prefer constructor injection where possible. The exceptions to the rule are for classes that are instantiated by the system - activities, fragments, etc.

One of the big benefits of constructor injection is that it makes your classes easier to test, it's easy to create an instance and replace the dependencies with mocks/fakes/whatever your preference is.

I believe there are some efficiency/performance benefits as well when using constructor injection with Dagger, less code-gen required, etc.

You should also look into using Hilt, which gets rid of all the boilerplate code:

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {

    private val viewModel: MainViewModel by viewModels()

    ...
}
@HiltViewModel
class MainViewModel @Inject constructor(
    private val repository: SomeRepository,
    private val useCase: SomeUseCase
) : ViewModel() {

    ....
}