在使用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);
    }

在使用structuremap的web api中,创建独立的依赖组件实例是线程安全的吗?

你所做的看起来非常正确。这正是你想要做的。

注意事项:

  1. 假设ITestService是TransientScoped的(默认),你的过滤器和你的控制器实际上会使用相同的ITestService实例。
  2. 如果你的DataContext是TransientScoped的,它将是每个请求唯一的(因为NestedContainer通过DependencyScope存储在请求上),所以你不应该看到你担心的竞争条件。
  3. 我知道有一些注意事项。其中之一是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或其他昂贵的查询确实会造成伤害,因为它们处理的每个请求都会被调用。

还有什么问题请问,我最近在这个领域做了很多事情,所以我对所有这些都有了相当不错的理解