Conor Gallagher
Conor Gallagher

Reputation: 1499

WebApi - Autofac cannot resolve parameter HttpRequestMessage

I have an issue with RegisterHttpRequestMessage not working for me and cannot figure out what I'm doing wrong. This is specifically when I try to manually resolve a service that accepts the HttpMessageRequest as a parameter.

I'm using modules to register components in my builder, and currently my module in the main web project looks like this:

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 is currently quite simple and looks like this:

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

GetSourceSystem is just an extension method that pulls out the header value. I have tried both registering SourceSystemViewModel with and without InstancePerRequest but it doesn't make a difference. The moment autofac tries to resolve ISourceSystemViewModal (and ultimately HttpRequestMessage) it throws this:

An exception of type 'Autofac.Core.Registration.ComponentNotRegisteredException' occurred in Autofac.dll but was not handled in user code

Additional information: The requested service 'System.Net.Http.HttpRequestMessage' has not been registered. To avoid this exception, either register a component to provide the service, check for service registration using IsRegistered(), or use the ResolveOptional() method to resolve an optional dependency.

Using autofac 3.5 (webapi dll is quoted as autofac.webapi2 3.4).

Any ideas much appreciated!

Notes

I'll add any findings as I come across them...

Update 1

I took a look at how RegisterHttpRequestMessage works and it does indeed add a message handler called CurrentRequestHandler to HttpConfiguration. When my request comes in I can see that this message handler still exists. So the method seems to do what it's supposed to, it's just not resolving the request message for me...

Update 2

I have noticed that while in the context of a controller and therefore have access to the HttpRequestMessage I can resolve both objects. Like this:

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

Update 3

It's important to note that I am manually trying to resolve a service that is expecting the HttpMessageRequest as an injected parameter. For example, this fails for me:

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

Upvotes: 2

Views: 2509

Answers (2)

Eric Eskildsen
Eric Eskildsen

Reputation: 4759

Even though this wasn't the issue for OP, here's another solution since this is currently the only Google result for "The requested service System.Net.Http.HttpRequestMessage' has not been registered."

If you've created an HttpConfiguration instance, make sure that's what you're passing to the registration function.

In my case, this was resolved by changing this:

builder.RegisterHttpRequestMessage(GlobalConfiguration.Configuration);

To this:

builder.RegisterHttpRequestMessage(Startup.HttpConfiguration);

Upvotes: 0

Rufus Buschart
Rufus Buschart

Reputation: 553

I had the same problem and based on SO I was able to get it working with

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

registering this module as

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

Upvotes: 4

Related Questions