在使用structuremap的web api中,创建独立的依赖组件实例是线程安全的吗?
本文关键字:实例 组件 依赖 线程 安全 独立 创建 structuremap web api | 更新日期: 2023-09-27 18:06:51
我有一个web api 2控制器:TestController.cs和一个动作过滤器:testauthorizeattributes .cs
我正在使用StructureMap。WebApi2 nuget包,用于设置Web API 2项目的依赖注入。
我试图在TestController.cs和testauthorizeattributes .cs中创建TestService对象的实例。
创建TestService实例的方法正确吗?
是否有可能多个线程似乎指的是Web API处理多个同时请求,这些请求以某种方式由相同的DataContext
处理请帮我了解一下下面提到的代码是否有问题。
[RoutePrefix("api/test")]
public class TestController : ApiController
{
public TestController(ITestService testService)
{
_testService = testService;
}
/// <summary>
/// Get details of individual test
/// </summary>
/// <param name="Id"> Id</param>
/// <param name="selectedSection">Selected Section</param>
/// <returns>Details of the Test</returns>
[Route("{Id:int}/{selectedSection?}", Name = "TestDetails")]
[HttpGet]
[TestAuthorize]
public HttpResponseMessage Get(int Id, string selectedSection = "")
{
var testDetails = _testService.GetTestResults(Id);
if (scan != null)
{
var progress = _testService.GetProgress(scan, user);
return Request.CreateResponse(HttpStatusCode.OK, scanDetails);
}
else
{
return Request.CreateResponse(HttpStatusCode.NotFound, new { error = GlobalConstants.ERROR_REVIEW_NOTFOUND });
}
}
}
[AttributeUsage(AttributeTargets.Method, Inherited = true)]
public class TestAuthorizeAttribute : ActionFilterAttribute
{
ITestService testService;
public ScanAuthorizeAttribute()
{
}
public override void OnActionExecuting(HttpActionContext actionContext)
{
_testService = actionContext.Request.GetDependencyScope().GetService(typeof(ITestService)) as ITestService;
var Id = Convert.ToInt32(actionContext.ActionArguments["Id"]);
var testDetails = _testService.GetTestResults(Id);
}
你所做的看起来非常正确。这正是你想要做的。
注意事项:
- 假设ITestService是TransientScoped的(默认),你的过滤器和你的控制器实际上会使用相同的ITestService实例。
- 如果你的DataContext是TransientScoped的,它将是每个请求唯一的(因为NestedContainer通过DependencyScope存储在请求上),所以你不应该看到你担心的竞争条件。
-
我知道有一些注意事项。其中之一是modelbinder和modelbinder提供程序是用System.Web.Http.ModelBinding.ModelBinderAttribute:
中的方法实例化的。private static object GetOrInstantiate(HttpConfiguration configuration, Type type) { return configuration.DependencyResolver.GetService(type) ?? Activator.CreateInstance(type); }
此方法不使用DependencyScope,因此这里使用的任何DBContext都将是完全唯一的(来自非嵌套容器的TransientScoped对象)
- 当我在webapi中处理IEnumerable依赖时,我看到了非常奇怪的竞态条件。StructureMap使用的默认ienumerable似乎不是线程安全的。小心过滤器、委托处理程序、模型绑定器等中的数据访问。在这些层中引入N+1或其他昂贵的查询确实会造成伤害,因为它们处理的每个请求都会被调用。
还有什么问题请问,我最近在这个领域做了很多事情,所以我对所有这些都有了相当不错的理解