带有依赖项注入的HttpContext.Items的WebApi等效项

ble*_*sle 5 unity-container asp.net-web-api

我正在构建一个ASP.NET WebApi 2.1应用程序,该应用程序需要与HttpContext.Items等效的每个请求缓存。

我什至不能在IIS托管下使用HttpContext,因为在服务/回购层(HttpContext.Current变为异步工作)时,HttpContext似乎丢失了(使用TPL调用,由于某些接口需要匹配,因此不进行异步/等待)空值)。

我使用的是unity 3.5,无法实现按请求进行正确的注入。尝试了HttpControllerActivator方法:

public class HttpControllerActivator : IHttpControllerActivator
{
    private readonly IUnityContainer _container;
    private readonly IHttpControllerActivator _activator;

    public HttpControllerActivator(IUnityContainer container, IHttpControllerActivator activator)
    {
        _container = container;
        _activator = activator;
    }

    public IHttpController Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
    {
        IHttpController controller = _activator.Create(request, controllerDescriptor, controllerType);
        _container.RegisterInstance<System.Net.Http.HttpRequestMessage>(request, new HierarchicalLifetimeManager());

        return controller;

    }
}
Run Code Online (Sandbox Code Playgroud)

但这会将HttpRequestMessage注册在根容器上,而不是在_activator.Create内部由BeginScope()调用创建的子容器上。结果,我在并发负载下得到混合请求实例。

知道如何解决这个问题吗?两天以来我一直在网上搜索,因此没有找到任何真正的解决方案...

Ste*_*ary 2

由于需要匹配某些接口,因此使用 TPL 调用,而不是 async/await

我建议您再看一下asyncawait。可以将其用于async您的实现部分并使其与其他异步 API 进行互操作

也就是说,如果你想保护HttpContext.Current(以及文化等),那么关键是SynchronizationContext。我有一篇关于该类型的 MSDN 文章,您可能会觉得有帮助。由于您的代码使用 TPL,因此您可能希望将请求上下文捕获到任务调度程序中:

var requestContext = TaskScheduler.FromCurrentSynchronizationContext();
Run Code Online (Sandbox Code Playgroud)

然后用它来安排你的任务继续。

ASP.NET 上的异步工作的另一个重要方面是确保运行时了解您的异步工作。您可以通过AsyncOperationManager.CreateOperation在异步工作开始之前调用注册异步工作并AsyncOperation.OperationCompleted通知运行时异步工作已完成来完成此操作。或者,您可以捕获SynchronizationContext.Current并调用SynchronizationContext.OperationStartedSynchronizationContext.OperationCompleted自己。

再次,再看一下asyncawait,看看是否可以使用它们;他们会为您处理所有像这样的细节。