Since the MessageHandlers
collection is global, it's effectively a list of singletons. This is fine when the handler itself has no state and no dependencies, but in a system that is based on the SOLID design principles, it's very likely that those handlers will have dependencies of their own and its very likely that some of those dependencies need a lifetime that is shorter than singleton.
If that's the case, such message handler should not be created as singleton, since in general, a component should never have a lifetime that is longer than the lifetime of its dependencies.
Web API however lacks any hooks that allow to resolve such handler on each request, but such mechanism is easily created by using a proxy class:
public class DelegatingHandlerProxy<TDelegatingHandler> : DelegatingHandler
where TDelegatingHandler : DelegatingHandler
{
private readonly WindsorContainer container;
public DelegatingHandlerProxy(WindsorContainer container)
{
this.container = container;
}
protected override async Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
// trigger the creation of the scope.
request.GetDependencyScope();
var handler = this.container.Resolve<TDelegatingHandler>();
handler.InnerHandler = this.InnerHandler;
var invoker = new HttpMessageInvoker(handler);
var response = await invoker.SendAsync(request, cancellationToken);
container.Release(handler);
return response;
}
}
This proxy can be used as follows:
GlobalConfiguration.Configuration.MessageHandlers.Add(
new DelegatingHandlerProxy<MyCustomHandler>(myContainer));
The proxy is a singleton, but it will resolve the specified MyCustomHandler
on each request.