WebApi - Autofac无法解析参数HttpRequestMessage

时间:2016-05-03 12:39:18

标签: c# asp.net-web-api asp.net-web-api2 autofac

我遇到问题RegisterHttpRequestMessage没有为我工作,也无法弄清楚我做错了什么。特别是当我尝试手动解析接受HttpMessageRequest作为参数的服务时。

我正在使用模块在我的构建器中注册组件,目前我在主Web项目中的模块如下所示:

builder.RegisterApiControllers(Assembly.GetExecutingAssembly());

builder.RegisterHttpRequestMessage(GlobalConfiguration.Configuration);
builder.RegisterType<SourceSystemViewModel>().AsImplementedInterfaces().InstancePerRequest();

builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
            .Where(t => t.Name.EndsWith("ViewModelValidator"))
            .AsImplementedInterfaces()
            .PropertiesAutowired();
// Etc etc etc

SourceSystemViewModel目前很简单,看起来像这样:

public interface ISourceSystemViewModel
{
    SourceSystem Value { get; }
}
public class SourceSystemViewModel : ISourceSystemViewModel
{
    public SourceSystemViewModel(HttpRequestMessage request)
    {
        Value = request.Headers.GetSourceSystem();
    }
    public SourceSystem Value { get; }
}

GetSourceSystem只是一种拉出标头值的扩展方法。我已经尝试使用SourceSystemViewModel注册InstancePerRequest,但没有区别。 autofac尝试解析ISourceSystemViewModal(最终HttpRequestMessage)的那一刻就抛出了这个:

  

类型的例外   发生'Autofac.Core.Registration.ComponentNotRegisteredException'   在Autofac.dll中但未在用户代码中处理

     

其他信息:请求的服务“System.Net.Http.HttpRequestMessage”尚未注册。避免   这个例外,要么注册一个组件来提供服务,   使用IsRegistered()检查服务注册,或使用   ResolveOptional()方法来解析可选的依赖项。

使用autofac 3.5(webapi dll引用为autofac.webapi2 3.4)。

任何想法都非常感激!

备注

我会在遇到他们时添加任何调查结果......

更新1

我看了RegisterHttpRequestMessage的工作原理,确实在CurrentRequestHandler添加了一个名为HttpConfiguration的消息处理程序。当我的请求进来时,我可以看到此消息处理程序仍然存在。所以方法似乎做它应该做的事情,它只是没有为我解决请求消息......

更新2

我注意到,在控制器的上下文中,因此可以访问HttpRequestMessage我可以解析这两个对象。像这样:

ILifetimeScope requestLifetimeScope = Request.GetDependencyScope().GetRequestLifetimeScope();
var h = requestLifetimeScope.Resolve<HttpRequestMessage>();
var sourceSystemViewModel = requestLifetimeScope.Resolve<ISourceSystemViewModel>();

更新3

重要的是要注意我手动尝试解析期望HttpMessageRequest作为注入参数的服务。例如,这对我来说失败了:

using (var httpRequestScope = IocProxy.Container.Context.BeginLifetimeScope("AutofacWebRequest"))
{
    var sourceSystemViewModel = httpRequestScope.Resolve<ISourceSystemViewModel>();
}

2 个答案:

答案 0 :(得分:4)

我遇到了同样的问题,基于SO我能够使用

    public class NLoggerTraceWriterModule : Module
{

    private HttpConfiguration _config;

    public NLoggerTraceWriterModule(HttpConfiguration config)
    {
        this._config = config;
    }

    protected override void Load(ContainerBuilder builder)
    {
        builder.RegisterInstance(this._config).As<HttpConfiguration>();
        builder.Register(c =>
                           c.Resolve<HttpConfiguration>()
                            .Services
                            .GetService(typeof(ITraceWriter)) as ITraceWriter)
               .As<ITraceWriter>();
    }
}

将此模块注册为

// Call RegisterHttpRequestMessage to add the feature.
builder.RegisterHttpRequestMessage(config);
builder.RegisterModule(new Helper.Logging.NLoggerTraceWriterModule(config));

答案 1 :(得分:0)

即使这不是OP的问题,但这是另一种解决方案,因为这是"The requested service System.Net.Http.HttpRequestMessage' has not been registered."的唯一Google搜索结果

如果您创建了HttpConfiguration实例,请确保将其传递给注册功能。

就我而言,这可以通过更改以下方法解决:

builder.RegisterHttpRequestMessage(GlobalConfiguration.Configuration);

对此:

builder.RegisterHttpRequestMessage(Startup.HttpConfiguration);