Inject WebAPI UrlHelper into service using Autofac

可紊 提交于 2019-12-09 09:30:46

问题


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.


回答1:


Use the RegisterHttpRequestMessage method to register the current request and then you can also register the URL helper like so:

public static IContainer SetupContainer(HttpConfiguration config)
{
    var containerBuilder = new ContainerBuilder();

    // Register your Web API.
    containerBuilder.RegisterApiControllers(Assembly.GetExecutingAssembly());
    containerBuilder.RegisterHttpRequestMessage(config);
    containerBuilder.Register(x => new UrlHelper(x.Resolve<HttpRequestMessage>()));  
    containerBuilder.RegisterWebApiFilterProvider(config);
    containerBuilder.RegisterWebApiModelBinderProvider();

    // Register your other types...

    var container = containerBuilder.Build();

    // Set the dependency resolver to be Autofac.
    config.DependencyResolver = new AutofacWebApiDependencyResolver(container);

    return container;
}



回答2:


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.




回答3:


Best I can think of is make your service implement IAutofacActionFilter like so

public class MyService : IAutofacActionFilter
    {
        private UrlHelper _urlHelper;

        public void DoSomething()
        {
            var link = Url.Link("SomeRoute", new {});
        }

        private UrlHelper Url
        {
            get
            {
                if(_urlHelper == null)
                    throw new InvalidOperationException();

                return _urlHelper;
            }
        }

        public void OnActionExecuted(System.Web.Http.Filters.HttpActionExecutedContext actionExecutedContext)
        {            
        }

        public void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
        {
            this._urlHelper = actionContext.Request.GetUrlHelper();
        }
    }

and then use something like the following Autofac config

builder.RegisterType<MyService>()
                 .AsWebApiActionFilterFor<SomeController>()
                 .AsSelf()
                 .InstancePerApiRequest();


来源:https://stackoverflow.com/questions/17294257/inject-webapi-urlhelper-into-service-using-autofac

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!