In my application i will be getting the various request from the single source, my job is to route the request to their particular handler. since my application uses the dagger am not able to route the request at run time.
data class MyRequestObj(type : Int, someInfo : String)
The above class is the request object that i send to route
interface RequestHandler{
fun performRequest(someInfo : String)
}
The above interface i will be extending in all the handler classes.
class Handler1 : RequestHandler{
@Override
fun performRequest(someInfo : String){
}
}
class Handler2 : RequestHandler{
@Override
fun performRequest(someInfo : String){
}
}
The above handler classes which implements RequestHandler
class Router @Inject constructor(handler1 : Handler1, handler2 :Handler2) {
fun routeRequest(request : MyRequestObj){
when(request.type){
TYPE1 -> handler1.performRequest(request.someInfo)
TYPE2 -> handler2.performRequest(request.someInfo)
}
}
}
The above class routes the request, my problem is i don't want to inject all my handlers at the constructor, i need to inject them at runtime using @Named in dagger or any other way based on its type.
Can anyone help me with this.
Use map Multibindings to create an injectable map of your Handlers. You can use Class
as keys for your handlers.
Map<Class<?>, Provider<RequestHandler>>
@Module
class HandlerModule {
@Provides @IntoMap
@ClassKey(Handler1.class)
fun provideHandler1() : RequestHandler {
return Handler1()
}
@Provides @IntoMap
@ClassKey(Handler1.class)
fun provideHandler2() : RequestHandler {
return Handler2()
}
}
You can then inject the map in your Router
class:
class Router @Inject constructor(
val handlerProviders: Map<Class<out RequestHandler>,
@JvmSuppressWildcards Provider<RequestHandler>>) {
fun routeRequest(request: MyRequestObj) {
val handler = when (request.type) {
TYPE1 -> handlerProviders.get(Handler1::class.java).get()
TYPE2 -> handlerProviders.get(Handler2::class.java).get()
else -> null
}
handler?.performRequest(request.someInfo)
}
}