9

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

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

我使用 Autofac 作为我的 IoC 容器。如何UrlHelper在容器中注册?它需要一个HttpRequestMessage,我不知道如何获取“当前”消息。

4

3 回答 3

9

使用该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;
}
于 2016-01-04T08:44:54.740 回答
5

根据 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();

UrlHelperMyService然后可以像任何其他依赖项一样注入到。

感谢 Darrel 为我指明了正确的方向。

于 2013-06-25T14:49:52.213 回答
0

我能想到的最好的就是让你的服务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();
于 2013-06-25T10:56:10.983 回答