问题描述
我创建了一个AmbientDataProvider
,旨在访问许多请求中设置的查询参数。在某些情况下,我想手动进行设置,例如
[HttpGet]
public IHttpActionResult SomeAction()
{
_ambientDataProvider.SetRequestId("123");
return Ok();
}
是否有必要将其保留为下面的AsyncLocal
?由于班级的生活方式有限,我想我也可以使用私有字符串吗?
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可供选择:Ambient Composition Model和Closure Composition Model。
您似乎混合了两种模型。使用Closure Composition Model,可以将运行时数据(您的请求ID)存储在组件内部的(私有)字段中,而使用Ambient Composition Model,则可以将运行时数据存储为环境状态(例如,使用AsyncLocal<T>
)。 / p>
使用环境组合模型时,可以使AmbientDataProvider
单身,因为AsyncLocal<T>
已经确保每个请求的运行时数据隔离。但是,当您的数据提供者是“合并范围”组件时,您也可以将数据存储在私有字段中。