Pregunta

I'm trying to integrate Hyprlinkr in a WebAPI project with Autofac.
I've started writing the custom IHttpControllerActivator but I get the following exception when trying to resolve the controller:

No scope with a Tag matching 'AutofacWebRequest' is visible from the scope in which the instance was requested. This generally indicates that a component registered as per-HTTP request is being requested by a SingleInstance() component (or a similar scenario.) Under the web integration always request dependencies from the DependencyResolver.Current or ILifetimeScopeProvider.RequestLifetime, never from the container itself.

Here's how the class looks like:

public class AutofacControllerActivator : IHttpControllerActivator
{
    private readonly IContainer _container;

    public AutofacControllerActivator(IContainer container)
    {
        if (container == null) throw new ArgumentNullException("container");
        _container = container;
    }

    public IHttpController Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
    {
        var linker = _container.ResolveOptional<RouteLinker>(
            new TypedParameter(typeof(HttpRequestMessage), request));

        return (IHttpController) _container.Resolve(controllerType,
            new TypedParameter(typeof(IResourceLinker), linker));
    }
}

How do I get the lifecycle issue fixed?

¿Fue útil?

Solución

You don't need to write you own IHttpControllerActivator because you can register the RouteLinker itself in the container.

You just need the help of the RegisterHttpRequestMessage method which makes the HttpRequestMessage resolvable from the container.

So your RouteLinker registration will look something like this:

builder.RegisterHttpRequestMessage(GlobalConfiguration.Configuration);
builder.Register(c => new RouteLinker(c.Resolve<HttpRequestMessage>()))
       .InstancePerApiRequest();

Now you can depend on the RouteLinker in your controllers:

public MyController : ApiController 
{
     public MyController(RouteLinker routeLinker)
     {
          //do stuff with routeLinker
     }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top