如何在Android中使用Dagger-2在运行时调用类方法

时间:2019-04-12 05:10:06

标签: android dependency-injection dagger-2 dagger

在我的应用程序中,我将从单一来源获取各种请求,我的工作是将请求路由到其特定处理程序。由于我的应用程序使用了匕首,因此无法在运行时路由请求。

data class MyRequestObj(type : Int, someInfo : String) 

上面的类是我发送到路由的请求对象

interface RequestHandler{
 fun performRequest(someInfo : String)
}

上述接口我将在所有处理程序类中扩展。

class Handler1 : RequestHandler{
  @Override
  fun performRequest(someInfo : String){

  }
}

class Handler2 : RequestHandler{
  @Override
  fun performRequest(someInfo : String){

  }
}

上述实现 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)
    }
  }
 }

上面的类路由请求,我的问题是我不想在构造函数中注入所有处理程序,我需要在运行时使用匕首或其他方式使用 @Named 注入它们根据其类型。

有人可以帮我吗?

1 个答案:

答案 0 :(得分:2)

使用地图Multibindings创建您的处理程序的可注入地图。您可以将Class用作处理程序的键。

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()
    }

}

然后您可以将地图插入您的Router类中:

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)
    }
}