2

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

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

我希望 MyHandler1 或 MyHandler2 由 MyHandler 动态添加到管道中,具体取决于某些条件。我知道 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);

    }
}

它确实有效,但我不确定这样做是否会破坏某些东西。我采取这种方法是否忽略了一些事情?

4

1 回答 1

0

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

于 2013-05-20T00:59:54.683 回答