即时添加消息处理程序

时间:2013-05-19 08:11:50

标签: asp.net-web-api

我有四个消息处理程序 - MyHandler,MyHandler1,MyHandler2和MyOtherHandler。我将MyHandler和MyOtherHandler添加到处理程序集合中,但不是MyHandler1或MyHandler2。

config.MessageHandlers.Add(new MyHandler());
config.MessageHandlers.Add(new MyOtherHandler());

我想通过MyHandler将MyHandler1或MyHandler2动态添加到管道中,具体取决于某些条件。我知道MyHandler1和2可以添加到config.MessageHandlers集合中,当轮到它时什么也不做,当'某些'条件不适用但不是我想要的。假设我有大约100个这样的处理程序,我不希望它们都在管道中运行,但只有在MyHandler认为合适时才会运行。

我无法通过设置MyHandler.InnerHandler手动将MyHandler1插入管道。链被全局缓存以用于所有请求,并且我无法针对与特定请求相关的内容对其进行修改。这就是我所做的。

我创建了一个基本处理程序,可以提高SendAsync的可见性。

public abstract class MyBaseHandler : DelegatingHandler
{

    public Task<HttpResponseMessage> WrapperSendAsync(
                                    HttpRequestMessage request,
                                        CancellationToken cancellationToken)
    {
        return this.SendAsync(request, cancellationToken);
    }
}

我从这个基地派生了MyHandler1和2。

public class MyHandler1 : MyBaseHandler
{
    protected async override Task<HttpResponseMessage> SendAsync(
                                    HttpRequestMessage request,
                                        CancellationToken cancellationToken)
    {
        // Use request

        var response = await base.SendAsync(request, cancellationToken);

        // Use response

        return response;

    }
}

现在,MyHandler可以根据条件实例化MyHandler1或Myhandler2,并将InnerHandler设置为自己的InnerHandler,只需通过包装器调用并返回SendAsync。

public class MyHandler : DelegatingHandler
{
    protected async override Task<HttpResponseMessage> SendAsync(
                                    HttpRequestMessage request,
                                        CancellationToken cancellationToken)
    {
        // Check condition and choose MyHandler1 or MyHandler2 or just return
        // await base.SendAsync(request, cancellationToken);
        var h = new MyHandler1();
        h.InnerHandler = this.InnerHandler;
        return await h.WrapperSendAsync(request, cancellationToken);

        // When MyHandler1 and MyHandler2 is no good, I just want
        // to do nothing and let the other handlers do their job
        // return await base.SendAsync(request, cancellationToken);

    }
}

它确实有效,但我不确定我是否通过这样做打破了一些东西。我是否通过这种方法忽略了一些事情?

1 个答案:

答案 0 :(得分:0)

你的方法看起来不错。我很确定它应该可以正常工作。