1

How can I add or remove message handlers at runtime? The following example does not work:

var logHandler = GlobalConfiguration.Configuration.MessageHandlers.FirstOrDefault(a => a.GetType() == typeof(ApiLogHandler));

if (logHandler == null)
{
    GlobalConfiguration.Configuration.MessageHandlers.Add(new ApiLogHandler());
}
else
{
    GlobalConfiguration.Configuration.MessageHandlers.Remove(logHandler);
}

The message handler is added to the list, but it is not called in the the next requests...

Mathias Colpaert
  • 652
  • 6
  • 23

1 Answers1

4

I would inject a MessageHandler into the configuration at startup that is built specifically to have a dynamic list of inner message handlers, and change the interface they use from DelegatingHandler to a custom one, e.g.

public interface ICustomMessageHandler 
{
    Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken);
}

After this, you can create a standard MessageHandler that contains a list of inner handlers:

public class DynamicMessageHandler : DelegatingHandler
{
    public List<ICustomMessageHandler> InnerHandlers { get; set; }

    public DynamicMessageHandler()
    {
        InnerHandlers = new List<ICustomMessageHandler>();
    }

    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        foreach (var innerHandler in InnerHandlers)
        {
            await innerHandler.SendAsync(request, cancellationToken);
        }

        return await base.SendAsync(request, cancellationToken);
    }
}

This way youshould be able to modify the list of InnerHandlers at runtime as long as you keep a single instance of DynamicMessageHandler around.

Hux
  • 3,102
  • 1
  • 26
  • 33
  • Thats smart, I will give it a try :) Any idea as to why the message handler can not reconfigure at runtime? – Mathias Colpaert May 18 '16 at 17:58
  • @MathiasColpaert I suspect the configuration is "finalised" once the `GlobalConfiguration.Configure` method is called. You could try calling that method again, but it seems that would be a one time usage method. – Hux May 18 '16 at 21:00
  • I tried that, calling Configure again does not work :) – Mathias Colpaert May 20 '16 at 06:42
  • And if you have a message handler that implements `ICustomMessageHandler` how do you exactly await the next handler in the pipeline if you want to do things in both the request and response? I mean you cannot do anymore `var response = await base.SendAsync(request, cancellationToken);` because there is no `base` anymore – diegosasw Aug 01 '17 at 14:34
  • If I can't it at start could I inject or add handler at runtime? – MichaelMao May 11 '18 at 09:01