【问题标题】:Simple service locator with generic type parameters in KotlinKotlin 中具有泛型类型参数的简单服务定位器
【发布时间】:2019-06-29 13:01:27
【问题描述】:

我按照these instructions 创建了一个简单的服务定位器,适应了 Kotlin 并且为了我的问题而更加简化:

object ServiceLocator {

    @JvmStatic
    fun getService(serviceName: String): Any {
        val service = lookupService(serviceName)

        if (service != null) {
            return service
        }

        throw UnknownServiceException()
    }

    private fun lookupService(serviceName: String): Any? {
        if (serviceName.equals("MyService")) {
            return MyService()
        }

        return null
    }
}

我可以这样使用它:

val myService = ServiceLocator.getService("MyService") as IMyService

我遇到的问题是myServiceAny 类型。如果getService 返回实际类型,我会更喜欢它。理想情况下,我想这样使用它:

val myService = ServiceLocator.getService<IMyService>()

或者,如果这是不可能的,这样的事情会很好:

val myService = ServiceLocator.getService(IMyService::class)

我不知道如何使泛型类型参数起作用。这是我尝试过的:

@JvmStatic
fun <T> getService(): T {
    val service = lookupService<T>()

    if (service != null) {
        return service
    }

    throw UnknownServiceException()
}

private fun <T> lookupService(): T? {
    if (T::class == IMyService::class) {
        return MyService()
    }

    return null
}

编译器抱怨两件事:

  1. T::class 上,它抱怨“不能使用 'T' 作为具体类型参数。请改用类。”
  2. return MyService() 上显示“类型不匹配。必需:T?找到:MyService”

【问题讨论】:

    标签: design-patterns kotlin inversion-of-control service-locator


    【解决方案1】:

    要在运行时访问类型T,而不必传入类(例如ServiceLocator.getService(IMyService::class)),您必须使用reified type parameter。这意味着您必须将方法更改为inline functions。这样做您可以将代码更新为以下内容:

    @JvmStatic
    inline fun <reified T> getService(): T {
        val service = lookupService<T>()
    
        if (service != null) {
            return service
        }
    
        throw UnknownServiceException()
    }
    
    inline fun <reified T> lookupService(): T? {
        if (T::class == IMyService::class) {
            return MyService() as T
        }
    
        return null
    }
    

    【讨论】:

    • 这意味着lookupService 也必须是公开的。可以保密吗?
    • 查看讨论here。希望对您有所帮助。
    猜你喜欢
    • 1970-01-01
    • 2011-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-03
    • 2010-10-04
    相关资源
    最近更新 更多