Capturing and injecting HttpRequestMessage in Web API with Ninject

ninject web api example
ninject not working with web api
ninject mvc and web api
dependency injection in web api step by step
ninject web api 2 controller
make sure that the controller has a parameterless public constructor ninject
ninject web api owin
ninject inject attribute

I've got a class that requires access to the HttpRequestMessage in my Web API service. At the moment, I've got the following code to capture the message in the pipeline and save it for later (based on this and this):

public class ContextCapturingControllerActivator : IHttpControllerActivator
{
    private readonly IKernel kernel;
    private HttpRequestMessage requestMessage;

    public ContextCapturingControllerActivator(IKernel kernel)
    {
        this.kernel = kernel;
    }

    public IHttpController Create(HttpRequestMessage requestMessage, 
                                  HttpControllerDescriptor controllerDescriptor, 
                                  Type controllerType)
    {
        this.kernel.Rebind<HttpRequestMessage>()
            .ToConstant<HttpRequestMessage>(requestMessage);

        var controller = (IHttpController)this.kernel.GetService(controllerType);

        this.requestMessage = requestMessage;
        requestMessage.RegisterForDispose(
            new Release(() => this.kernel.Release(controller)));

        return controller; 
    }

    private class Release : IDisposable
    {
        private readonly Action release;

        public Release(Action release)
        {
            this.release = release;
        }

        public void Dispose()
        {
            this.release();
        }
    }
}

In my composition root, I configure the ControllerActivator:

kernel.Bind<IHttpControllerActivator>()
      .To<ContextCapturingControllerActivator>();

The end result is that from the perspective of the configuration, the HttpRequestMessage is "magically" injected wherever it is requested since it is done for us inside the ControllerActivator. I have not been able to inject the message from my composition root. I'm also not crazy about the Rebind since it's there to avoid adding a new binding every time the service is called. I suspect it's due to the singleton nature of the Web API stack, but have not been able to sort out how to deal with that properly.

In general, I cannot use the latest unstable Nuget package of Ninject web api due to the error reported (and ignored) here.

Can anyone suggest the proper way to improve my code to make it a bit more clear and make life easier for future maintainers (and let's face it -- that's probably going to be me).

Thanks.

Here is what I did, but I believe it depends on Web API 2.0+.

I created an instance class that wraps the current context's http request:

public class HttpRequestMessageWrapper
{
    private readonly HttpRequestMessage m_httpRequestMessage;

    public HttpRequestMessageWrapper()
    {
        m_httpRequestMessage = HttpContext.Current.Items["MS_HttpRequestMessage"] as HttpRequestMessage;
    }

    public HttpRequestMessage RequestMessage
    {
        get
        {
            return m_httpRequestMessage;
        }
    }
}

Then I bound the HttpRequestMessage to the property with the ToMethod binding in request scope.

container.Bind<HttpRequestMessage>().ToMethod(ctx => new HttpRequestMessageWrapper().RequestMessage).InRequestScope();

Capturing and injecting HttpRequestMessage in Web API with , Capturing and injecting HttpRequestMessage in Web API with Ninject - asp.net- web-api. Web API creates the controller when it routes the request, and Web API doesn't know anything about IProductRepository. This is where the Web API dependency resolver comes in. The Web API Dependency Resolver. Web API defines the IDependencyResolver interface for resolving dependencies. Here is the definition of the interface:

I've tried the method that @Mackers proposed which is the cleanest way.... however, in my specific scenario, it didn't work due to a timing issue. For my case, I needed to inject an object into the apicontroller ctor and that object required the HttpRequestMessage. The HttpContext.Current.Items["MS_HttpRequestMessage"]isn't populated until the controller has been constructed and initialized and I couldn't find any other way to access it. So I resorted to creating a custom DelegatingHandler and rebinding the current request message as they come in.

public class CurrentHttpRequestMessageHandler : DelegatingHandler
    {
        [SecuritySafeCritical]
        protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            UpdateScopeWithHttpRequestMessage(request);

            return base.SendAsync(request, cancellationToken);
        }

        internal static void UpdateScopeWithHttpRequestMessage(HttpRequestMessage request)
        {
            NinjectConfig.GetConfiguredKernel().Rebind<HttpRequestMessage>().ToMethod(ctx => { return request; })
                .InRequestScope();
        }
    }

The GetConfiguredKernel is a static method I created to simply return the static Kernel instance already configured.

 public class NinjectConfig
    {
        private static readonly Bootstrapper bootstrapper = new Bootstrapper();
        private static StandardKernel _kernel;

        public static void Start()
        {
            DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
            DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
            bootstrapper.Initialize(CreateKernel);
        }

        public static IKernel GetConfiguredKernel()
        {
            if (_kernel != null)
                return _kernel;

            return CreateKernel();
        }
        ....

Then register the DelegatingHandler with the HttpConfiguration:

config.MessageHandlers.Add(new CurrentHttpRequestMessageHandler());

Web API 2 and ninject, how to make them work together, Capturing and injecting HttpRequestMessage in Web API with Ninject 1.asp.net web api - Capturing and injecting Description:I've got a class� In this article I will show you Dependency Injection in the Web API using Ninject. The following is the procedure for creating the application. Step 1. Create a Web API application as in the following: Start Visual Studio 2012. From the start window Select "Installed" -> "Visual C#" -> "Web".

Building off of Macker's answer, System.Web has an HttpRequestBase class that you can use and simplify unit testing the code. Anywhere in the code that the request is required, specify the HttpRequestBase type as the constructor parameter and register it with the below method:

Ninject example:

Bind<HttpRequestBase>().ToMethod(context => new HttpRequestWrapper(HttpContext.Current.Request));

Unity example:

container.RegisterType<HttpRequestBase>(new InjectionFactory(_ => new HttpRequestWrapper(HttpContext.Current.Request)));

WebApi failing to resolve dependencies, Nuget packages. Add Ninject.Web.WebApi using nuget to your Web Api project. That will install two other package dependencies: Ninject Introduction to Ninject in ASP.NET Web API Ninject is a light-weighted, flexible and open source dependency injector for .Net applications. Due to its flexible nature, managing the application at code level becomes easier and reusable.

asp.net-web-api, The issue is where you're initializing the Web API DependencyResolver in the Sitecore initialize pipeline. In Sitecore 8.2, the part of the initialize pipeline where the MVC and Web API InRequestScope(); //Ninject builder. ApiController registration line AFTER the registration that captures the IEntityAccess class, it should� Open Visual Studio => New Project => Web => Visual Studio 2012 => ASP.Net MVC 4 Web Application, give a nice name to your project and click OK. Step 2 Select Empty Template => OK and your solution is ready. Step 3

Dependency injection in aspnet web api using autofac, 我有一个类,该类需要访问Web API服务中的HttpRequestMessage。 目前 Capturing and injecting HttpRequestMessage in Web API with Ninject 通常, 由于此处报告(并忽略了)错误,因此我无法使用Ninject Web api的最新不� InRequestScope. For web applications you can use InRequestScope() to have Ninject create a single instance for each request handled by your application. For InRequestScope() bound instances, Ninject will use HttpContext.Current in case of HTTP applications and OperationContext.Current in case of WCF requests as the scoping object.

Restsharp dependency injection, NET WebAPI , I will be enabling the ProductController to use the Ninject Dependency Injection which is a way to implement Inversion Of Control (IOC) design pattern. Oct 16, 2016 � In my AlbumViewer API I capture all errors using an MVC Task<HttpResponseMessage> SendAsync( HttpRequestMessage request,� Ninject.Web.Common.WebHost This will pull down the WebActivatorEx package and add a new class called NinjectWebCommon to your App_Start directory. 2. Edit NinjectWebCommon.cs. NinjectWebCommon.cs is missing a key feature if you want to use ninject to construct the controllers, and I presume that is why you are using ninject inside a Web Api

Comments
  • I've had to do the same recently with Ninject (and previously with StructureMap) and have yet to find a better solution.
  • @BenFoster I've since switched to Autofac (for many reasons, not just this issue), and while it provides a cleaner way to inject the HttpRequestMessage into running code, I haven't been able to access it in my in-memory integration tests. So, each DI framework seems to have its own unique trade-offs.
  • Any break through? I have the same problem...
  • I have the same problem. Using this solution above causes my CPU to spike to 100 because the bindings are stored in a static dictionary. When multiple requests come through, they are contending because of each thread's attempt to enumerate the dictionary. :( Anyone find another way of doing this? @Hudvoy? @BenFoster?