环境数据作为 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 组件时,您还可以将数据存储在私有字段中。
我创建了一个 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 组件时,您还可以将数据存储在私有字段中。