繁体   English   中英

使用Autofac将WebAPI UrlHelper注入服务

[英]Inject WebAPI UrlHelper into service using Autofac

我的WebAPI项目中有一些控制器使用的服务。 该服务需要生成URL,因此理想情况下它将通过构造函数参数获取UrlHelper

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

我正在使用Autofac作为我的IoC容器。 如何在容器中注册UrlHelper 它需要一个HttpRequestMessage ,我无法弄清楚如何获取“当前”消息。

使用RegisterHttpRequestMessage方法注册当前请求,然后您也可以注册URL助手,如下所示:

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;
}

根据Darrel Miller的评论,我创建了以下内容:

一个简单的容器类,用于保存对“当前”HttpRequestMessage的引用

public class CurrentRequest
{
    public HttpRequestMessage Value { get; set; }
}

将存储当前请求的消息处理程序

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);
    }
}

在Global.asax中,配置WebAPI时,添加消息处理程序。

GlobalConfiguration.Configuration.MessageHandlers.Insert(0, new CurrentRequestHandler());

然后,配置Autofac容器以使其构造UrlHelper ,从CurrentRequest对象获取当前请求。

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注入到MyService

感谢Darrel指出我正确的方向。

我能想到的最好就是让你的服务实现IAutofacActionFilter

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();
        }
    }

然后使用类似下面的Autofac配置

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM