环境数据作为 AsyncLocal

Ambient data as AsyncLocal

我创建了一个 AmbientDataProvider,旨在访问在我的许多请求中设置的查询参数。在少数情况下,我想手动设置它,例如

[HttpGet]
public IHttpActionResult SomeAction()
{
    _ambientDataProvider.SetRequestId("123");

    return Ok();
} 

保持下面的 AsyncLocal 有什么意义吗?由于 class 有范围的生活方式,我想我还不如使用私有字符串?

public class AmbientDataProvider : IAmbientDataProvider
{
    private readonly AsyncLocal<string> _requestId = new AsyncLocal<string>();
    public string RequestId => _requestId.Value ?? HttpContext.Current?.Request.QueryString["requestId"];

    public void SetRequestId(string requestId)
    {
        _requestId.Value = requestId;
    }
}

我的容器配置

container.Options.DefaultScopedLifestyle = new WebRequestLifestyle();
container.Register<IAmbientDataProvider, AmbientDataProvider>(Lifestyle.Scoped);

在通过对象图推送运行时数据时,有两个 DI Composition Models to choose from: Ambient Composition Model and Closure Composition Model

您似乎混用了这两种模型。使用闭包组合模型,您可以将运行时数据(您的请求 ID)存储在组件内的(私有)字段中,而使用环境组合模型,您可以将该运行时数据存储为环境状态(例如使用 AsyncLocal<T>)。

使用环境组合模型时,您可以创建 AmbientDataProvider 单例,因为 AsyncLocal<T> 已经确保每个请求的运行时数据隔离。但是,当您的数据提供者是 Scoped 组件时,您还可以将数据存储在私有字段中。