通过 Key class 访问 CoroutineContext 元素

Access CoroutineContext element via Key class

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

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 的 class 获取 MyElement 的实例,因为我希望能够,例如,获取 HttpClient 中的值服务层,而不必一直沿链向下传递 ele.key。可能吗?

我问的问题与 How to make request-bound data globally available in Ktor? 基本相同,不幸的是没有人回答。

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

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

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