通过Key类

问题描述

在Ktor中,我希望实现某种方法来引用coroutineContext内部的键值对,而不会在方法参数中拖动对对象的引用。基于https://proandroiddev.com/demystifying-coroutinecontext-1ce5b68407ad,我编写了参考类:

class MyElement(override val key: CoroutineContext.Key<*>,val value: String) : CoroutineContext.Element
class MyKey: CoroutineContext.Key<MyElement>

... //内部路由:

val key: CoroutineContext.Key<MyElement> = MyKey()
val ele = MyElement(key,"myJWT")
withContext(coroutineContext + ele) {
    val notNullEle : MyElement = coroutineContext[ele.key] as MyElement // not null
    logger.info(notNullEle.value) // "myJWT"
    val shouldNotBeNullEle = coroutineContext[MyKey()]// NULL!
}
val shouldBeNull = coroutineContext[ele.key] // is and should be null
val shouldBeNull2 = coroutineContext[MyKey()] // is and should also be null

当我将ele.key发送到coroutineContext[ele.key]时,我得到了正确的元素,但是当我一起发送MyKey的新实例时,我得到的是null,因此MyElement的实例清楚地映射到的实例。钥匙。但是,这对于我的目的来说并不是很好,因为我希望使用MyKey类来获取MyElement的实例,因为我希望能够例如在服务层中获取HttpClient中的值而不必将ele.key一直传递到整个链。有可能吗?

我要问的基本上与How to make request-bound data globally available in Ktor?相同,但不幸的是没有得到答复。

解决方法

如您所链接的文章中所述,您可以将CoroutineContext视为以Map为键的CoroutineContext.Key

鉴于此前提,您遇到的问题很清楚,ele.key != MyKey()或键在定义上不等效,因此它们将不会在上下文Map中返回相同的条目。

这就是大多数CoroutineContext.Key实现都是object的原因,因为它基于对象单例实现了equals方法。您可能还需要使用object或正确实现equalshashCode