Based on Darrel Miller's comment, I created the following:
A simple container class to hold a reference to the "current" HttpRequestMessage
public class CurrentRequest
{
public HttpRequestMessage Value { get; set; }
}
A message handler that will store the current request
public class CurrentRequestHandler : DelegatingHandler
{
protected async override System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
{
var scope = request.GetDependencyScope();
var currentRequest = (CurrentRequest)scope.GetService(typeof(CurrentRequest));
currentRequest.Value = request;
return await base.SendAsync(request, cancellationToken);
}
}
In Global.asax, when configuring WebAPI, add the message handler.
GlobalConfiguration.Configuration.MessageHandlers.Insert(0, new CurrentRequestHandler());
Then, configure the Autofac container to let it construct UrlHelper
, getting the current request from the CurrentRequest
object.
var builder = new ContainerBuilder();
builder.RegisterType<CurrentRequest>().InstancePerApiRequest();
builder.Register(c => new UrlHelper(c.Resolve<CurrentRequest>().Value));
builder.RegisterType<MyService>();
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
...
container = builder.Build();
UrlHelper
can then be injected into the MyService
just like any other dependency.
Thanks to Darrel for pointing me in the right direction.