具有依赖注入的HttpContext.Items的WebApi等价物

时间:2014-04-30 18:38:04

标签: asp.net-web-api unity-container

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

即使在IIS托管下我也无法使用HttpContext,因为当我在服务/ repos层中进行异步工作(使用TPL调用,而不是async / await,因为某些需要匹配的接口)时,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()调用创建的子容器。结果,我在并发加载下获得混合请求实例。

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

1 个答案:

答案 0 :(得分:2)

  

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

我建议您再看一下asyncawait。您可以使用async作为实施的一部分,have it interoperate with other asynchronous APIs

如果你想保留HttpContext.Current(以及文化等),那么关键是SynchronizationContext。我有MSDN article on that type您可能会觉得有帮助。由于您的代码使用的是TPL,您可能希望将请求上下文捕获到任务调度程序中:

var requestContext = TaskScheduler.FromCurrentSynchronizationContext();

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

ASP.NET上异步工作的另一个重要方面是确保运行时知道您的异步工作。您可以通过调用AsyncOperationManager.CreateOperation来启动异步工作,然后AsyncOperation.OperationCompleted通知运行时异步工作已完成。或者,您可以捕获SynchronizationContext.Current并自己致电SynchronizationContext.OperationStartedSynchronizationContext.OperationCompleted

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