在科特林泛型类型参数的简单的服务定位器

问题描述 投票:0回答:1

我跟着these instructions创建一个简单的服务定位器,适用于科特林和简化更对我的问题的目的:

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

我有这样的问题是myService的类型是Any的。我喜欢它,如果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个回答
2
投票

要访问的类型,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
}
© www.soinside.com 2019 - 2024. All rights reserved.