Skip to content

Dagger ‐ Field injection

Devrath edited this page Oct 6, 2023 · 9 revisions

Observations

  • You can clearly see there are three implementations(Wheels, Engine, and Car).
  • We always use constructor injection wherever possible but sometimes in scenarios, we cannot access/modify the constructor and we need to use the field-injection.
  • field-injection in android is usually used in framework classes like activities,fragments etc., where we cannot edit the constructor of a class.
  • The way we build the Dagger component is different here since we need access to context of the class we are injecting.
// Dagger generates the component from it we can build the component 
val mobileComponent = DaggerMobileComponent.builder().build()
// Here we pass the context of the activity since we need the context for field injection for dagger
mobileComponent.inject(this@DaggerConceptsActivity)
// Access the methods of the class from the field-injected variable
mobile.runMobile()
  • We inject using the inject annotation as below
@Inject lateinit var mobile : Mobile
  • In the output you can observe that, Dagger tries to construct the Mobile class and finds the Battery and Screen, So it first constructs the Battery and Screen and then the Mobile.

Output

Battery constructor is invoked !
Screen constructor is invoked !
Mobile constructor is invoked !
Mobile is running !

Code

implementations

Battery.kt

class Battery @Inject constructor() {

    init {
        printLog("Battery constructor is invoked !")
    }

}

Screen.kt

class Screen @Inject constructor(){

    init {
        printLog("Screen constructor is invoked !")
    }

}

Mobile.kt

class Mobile @Inject constructor( var battery: Battery, var screen: Screen){

    init { printLog("Mobile constructor is invoked !") }

    fun runMobile() { printLog("Mobile is running !") }

}

Components

MobileComponent.kt

@Component
interface MobileComponent {

    fun inject(activity: MyActivity)

}

Activities

MyActivity.kt

class MyActivity : AppCompatActivity() {

    private lateinit var binding: ActivityDaggerConceptsBinding

    @Inject
    lateinit var mobile : Mobile

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityDaggerConceptsBinding.inflate(layoutInflater)
        setContentView(binding.root)
        setOnClickListener()
    }

    private fun setOnClickListener() {
        binding.apply {
            // Field Injection
            fieldInjectionId.setOnClickListener {
                val mobileComponent = MyActivity.builder().build()
                mobileComponent.inject(this@MyActivity)
                mobile.runMobile()
            }
        }
    }
}
Clone this wiki locally