通过 Key 类访问 CoroutineContext 元素

Myr*_*SC2 1 kotlin ktor kotlin-coroutines

在 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>
Run Code Online (Sandbox Code Playgroud)

... // 内部路由:

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
Run Code Online (Sandbox Code Playgroud)

当我发送ele.keycoroutineContext[ele.key],我得到了正确的元素,但是当我发送 MyKey 的新实例时,我得到 null,因此 MyElement 的实例清楚地映射到键的实例。然而,这对我的目的来说效果不佳,因为我希望使用 MyKey 类获取 MyElement 的实例,因为我希望能够获取服务层中 HttpClient 中的值,而无需使用ele.key一路向下传递。是否可以?

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

Kis*_*kae 6

正如您链接的文章中所述,您可以将 视为CoroutineContextaMap作为CoroutineContext.Key其键。

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

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