androidkotlindependency-injectiondagger-hilt

@Inject lateinit var vs @Inject constructor on Dagger Hilt


Reading documentation, I found that it's possible to use Hilt by these two ways:

  1. @Inject lateinit var on just the class fields you wanna inject
  2. @Inject constructor

I'm trying to figure out which option is better. I personally found an issue on @Inject constructor. When I need to pass non Hilt parameters to the constructor, it requires you to generate a lot of boilerplate code that only forces you to add more complexity to your project. For example:

Having a class like this:

@AndroidEntryPoint 
class CustomClass @Inject constructor (val repository: Repository, val name: String) {

Let's say I only want to inject the repository parameter, but I want to pass the name parameter during initialization like so:

val customClass = CustomClass("name")

with @Inject constructor I'm forced to add a lot of boirlerplate and complexity:

@AndroidEntryPoint 
class CustomClass @AssisgtedInject constructor (
    val repository: Repository, 
    @Assisted val name: String
) {

    @AssistedFactory
    interface CustomClassFactory {
        fun create(name: String): CustomClass
    }
}

To add more boilerplate and useless complexity, that forces you to create the CustomClass class with the interface instead of the normal class, and calling the create method.

On the other hand, if you instead do it using @Inject lateinit var, is that simple:

@AndroidEntryPoint 
class CustomClass(val name: String) {
    @Inject lateinit var repository: Repository
}

Now, think that this is a super simple example with just one non Hilt parameter, but this can get a lot more big as you know.

So, why almost every sample project is using @Inject constructor if @Inject lateinit var is a much more better option? What I'm lossing here?


Solution

  • Its not like one is better than the other. Each have their pros and cons. I can see a few benefits of using the constructor based approach:

    1. dependencies are immutable as you are not using var
    2. easier to mock dependencies during test
    3. has clear dependencies as they are present in the constructor and not somewhere inside the class.