Skip to content

Dagger ‐ Injecting values at runtime by creating module

Devrath edited this page Oct 6, 2023 · 5 revisions

Observations

  • In projects sometimes we might need to pass the values dynamically, This means when we are creating the components(activity .. etc.) and not when dagger generates the code.
  • So appropriate variable as placeholders has to be set during the generation stage itself so that we can pass values for those variables.
  • In the output you can see that we had passed the dynamic value 20 from activity when the activity is being constructed.

Output

WatchBattery constructor is invoked !
Watch class constructor is invoked !
buildWatch method in watch class is invoked with capacity 20

Code

implementations

WatchBattery.kt

class WatchBattery @Inject constructor(
    private var batteryCapacity: Int
){

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

    fun startBatteryConfig(){
        printLog("WatchBattery started with configuration -> $batteryCapacity")
    }

    fun getCapacity(): Int {
        return batteryCapacity
    }

}

Watch.kt

class Watch @Inject constructor(
    private val watchBattery : WatchBattery
){

    init {
        printLog("Watch class constructor is invoked !")
    }

    fun buildWatch() {
        val capacity = watchBattery.getCapacity()
        printLog(
            "buildWatch method in watch class is invoked " +
            "with capacity $capacity"
        )
    }
}

Modules

WatchModule.kt

@Module
@DisableInstallInCheck
class WatchModule(private var batteryCapacity: Int) {

    @Provides
    fun provideBattery() : WatchBattery {
        return WatchBattery(batteryCapacity)
    }

    @Provides
    fun provideWatch(watchBattery: WatchBattery) : Watch {
        return Watch(watchBattery)
    }

}

Components

WatchComponent.kt

@Component(modules = [WatchModule::class])
interface WatchComponent {
    fun getWatch(): Watch
}

Activity

MyActivity.kt

class DaggerConceptsActivity : AppCompatActivity() {

    private lateinit var binding: ActivityDaggerConceptsBinding

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

    private fun setOnClickListener() {
        binding.apply {
            // Injecting values at runtime - Using module
            injectValAtRuntimeId.setOnClickListener {
                val comp = DaggerWatchComponent.builder().watchModule(WatchModule(20)).build()
                comp.getWatch().buildWatch()
            }
        }
    }
}
Clone this wiki locally