Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inject WebAPI UrlHelper into service using Autofac

I have a service used by a few controllers in my WebAPI project. The service needs to generate URLs, so ideally it would get a UrlHelper via a constructor parameter.

public class MyService
{
    public MyService(UrlHelper urlHelper) { ... }
}

I'm using Autofac as my IoC container. How can I register UrlHelper in the container? It needs a HttpRequestMessage and I can't figure out how to get the "current" message.

like image 722
Andrew Davey Avatar asked Jun 25 '13 09:06

Andrew Davey


People also ask

Why use Autofac?

AutoFac provides better integration for the ASP.NET MVC framework and is developed using Google code. AutoFac manages the dependencies of classes so that the application may be easy to change when it is scaled up in size and complexity.

What is Autofac dependency injection?

Autofac is an addictive IoC container for . NET. It manages the dependencies between classes so that applications stay easy to change as they grow in size and complexity. This is achieved by treating regular . NET classes as components.


1 Answers

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.

like image 97
Andrew Davey Avatar answered Nov 15 '22 19:11

Andrew Davey