的WebAPI相当于HttpContext.Items与依赖注入 [英] WebApi equivalent for HttpContext.Items with Dependency Injection

查看:187
本文介绍了的WebAPI相当于HttpContext.Items与依赖注入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

由于HttpContext的,似乎当我做异步工作要丢了,我不能使用的HttpContext即使在IIS托管(使用TPL调用,而不是异步/的await由于一些接口需要相匹配)的服务/回购层(HttpContext的.Current变为零)。

我使用统一3.5并不能达到做一个适当的每个请求注入。试过HttpControllerActivator方式:

 公共类HttpControllerActivator:IHttpControllerActivator
{
    私人只读IUnityContainer _container;
    私人只读IHttpControllerActivator _activator;    公共HttpControllerActivator(IUnityContainer容器,IHttpControllerActivator激活)
    {
        _container =容器;
        _activator =激活;
    }    公共IHttpController创建(HTT prequestMessage要求,HttpControllerDescriptor controllerDescriptor,类型controllerType)
    {
        IHttpController控制器= _activator.Create(请求controllerDescriptor,controllerType);
        _container.RegisterInstance&所述; System.Net.Http.Htt prequestMessage>(请求,新HierarchicalLifetimeManager());        返回控制器;    }
}

但这个注册的Htt prequestMessage根容器,不是孩子一家由BeginScope()创建内部_activator.Create呼吁。这样一来,我的并发负载下获得混合请求实例。

不知道如何解决呢?因为这两天我在网上我搜索,并没有发现任何真正的解决这个问题...


解决方案

  使用TPL呼叫

,而不是异步/ AWAIT由于需要进行匹配一些接口


我建议你再看看异步的await 。它可以使用异步并为您实现的一部分的有它与其他异步API的互操作。

这是说,如果你想preserve HttpContext.Current (以及文化等),那么关键就是 SynchronizationContext的。我有href=\"http://msdn.microsoft.com/en-us/magazine/gg598924.aspx\" rel=\"nofollow\">对你有帮助的那种类型 MSDN文章的

  VAR的RequestContext = TaskScheduler.FromCurrentSynchronizationContext();

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

在ASP.NET的异步工作的另一个重要方面是确保运行时知道你的异步工作。你可以通过调用 AsyncOperationManager.CreateOperation 这样对注册工作同步启动,并在 AsyncOperation.OperationCompleted 通知运行该异步工作已完成。或者,您可以捕捉到 SynchronizationContext.Current 和呼叫 SynchronizationContext.OperationStarted SynchronizationContext.OperationCompleted 自己。

再次再看看异步等待,看看它是否在所有可能使用的;他们会照顾这样所有的相关细节给你。

I'm building an ASP.NET WebApi 2.1 app that needs an equivalent of HttpContext.Items as a per request cache.

I cannot use HttpContext even under IIS hosting because HttpContext seems to be lost when i'm doing async work (using TPL calls, not async/await due to some interface that needs to be matched) in services/repos layers (HttpContext.Current becomes null).

I'm using unity 3.5 and cannot achieve to do a proper per request injection. Tried the HttpControllerActivator method :

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;

    }
}

But this register the HttpRequestMessage on the root container, not the child one created by the BeginScope() call inside _activator.Create. As a result, I'm getting mixed requests instances under concurrent load.

Any idea how to solves this ? I'm searching online since two days and haven't find any real solution to that matter...

解决方案

using TPL calls, not async/await due to some interface that needs to be matched

I recommend you take another look at async and await. It is possible to use async for your part of the implementation and have it interoperate with other asynchronous APIs.

That said, if you want to preserve HttpContext.Current (as well as culture, etc.), then the key is SynchronizationContext. I have an MSDN article on that type that you may find helpful. Since your code is using TPL, you would probably want to capture the request context into a task scheduler:

var requestContext = TaskScheduler.FromCurrentSynchronizationContext();

and then use that to schedule your task continuations.

The other important aspect of asynchronous work on ASP.NET is to ensure that the runtime is aware of your asynchronous work. You can do this by calling AsyncOperationManager.CreateOperation to register asynchronous work before it starts and AsyncOperation.OperationCompleted to notify the runtime that the asynchronous work has completed. Alternatively, you can capture the SynchronizationContext.Current and call SynchronizationContext.OperationStarted and SynchronizationContext.OperationCompleted yourself.

Again, take another look at async and await and see if it's at all possible to use them; they'll take care of all the gritty details like this for you.

这篇关于的WebAPI相当于HttpContext.Items与依赖注入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆