asp.net web api-WebApi等价于HttpContext.Items的依赖注入



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

即使在IIS托管下,我也不能使用HttpContext,因为当我在服务/repo层中进行异步工作(使用TPL调用,而不是异步/等待,因为需要匹配一些接口(时,HttpContext似乎丢失了(HttpContext.Current变为null(。

我使用的是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;
    }
}

但这在根容器上注册了HttpRequestMessage,而不是由_activator.Create内的BeginScope((调用创建的子容器。因此,我在并发加载下得到了混合请求实例。

知道如何解决这个问题吗?我在网上搜索了两天,还没有找到任何真正的解决方案。。。

使用TPL调用,而不是异步/等待,因为某些接口需要匹配

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

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

var requestContext = TaskScheduler.FromCurrentSynchronizationContext();

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

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

再次看一下asyncawait,看看是否可以使用它们;他们会帮你处理所有这些棘手的细节。

最新更新