i need to inject the class at runtime using dagger. what my problem is am getting compile time error while injecting the class locally in method and also i was not able to inject at runtime without using constant for @Named
Example
interface PerformActionInterface{
fun performAction()
}
class P1 : PerformActionInterface{
override fun performAction(){
}
}
class P2 : PerformActionInterface{
override fun performAction(){
}
}
class PerformAction @Inject constructor(){
fun perform(name : String){
@Inject
@Named(name)
performActionInterface : PerformActionInterface
performActionInterface.performAction()
}
}
were as in dagger implementation i will be doing like this
@Binds
@Named("p1")
abstract bindP1Class(p1 : P1) :PerformActionInterface
@Binds
@Named("p2")
abstract bindP1Class(p2 : P2) :PerformActionInterface
Any help for how to inject this at runtime ?
You can't annotate something in runtime, the element value in Java annotation has to be a constant expression.
But this use case can be solved by map multibind.
In your Module
, in addition to just @Bind
or @Provide
, also annotate the abstract fun with @IntoMap
and the map key (sorry for any error in my Kotlin)
@Binds
@IntoMap
@StringKey("p1")
abstract fun bindP1Class(p1: P1): PerformActionInterface
@Binds
@IntoMap
@StringKey("p2")
abstract fun bindP2Class(p2: P2): PerformActionInterface
Then in your PerformAction
class, declare a dependency of a map from String
to PerformActionInterface
, and do whatever with the map:
// map value type can be Lazy<> or Provider<> as needed
class PerformAction @Inject constructor(
val map: Map<String, @JvmSuppressWildcards PerformActionInterface>) {
fun perform(name: String) {
map.get(name)?.performAction()
// or do something if the get returns null
}
}