Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Injecting Service in Middleware in ASP.NET Core

I want to inject a service based on the HTTP header value. So I have 2 classes - DbDataProvider and InMemDataProvider, both are implemented from IDataProvider. Whenever an API call is made, a header is passed by the client which determines whether DbDataProvider is required or InMemDataProvider is required. How do I achieve that? So in short I need to inject service in the ServiceCollection in one of the middlewares. Is that possible?

The problem is that in the ConfigureService method in Startup class I cannot get the HttpContext. I have written a middleware using which I am able to get the HTTP Context but how do I inject a Service there?

like image 747
Pratik Bhattacharya Avatar asked Jul 03 '16 21:07

Pratik Bhattacharya


People also ask

What is dependency injection middle ware in ASP.NET Core?

ASP.NET Core - Dependency Injection. ASP.NET Core is designed from scratch to support Dependency Injection. ASP.NET Core injects objects of dependency classes through constructor or method by using built-in IoC container.

What is middleware in .NET Core and how is it injected in the request pipeline?

Middleware is software that's assembled into an app pipeline to handle requests and responses. Each component: Chooses whether to pass the request to the next component in the pipeline. Can perform work before and after the next component in the pipeline.


1 Answers

You can achieve this in your DI config in Startup.cs.

They key is services.AddHttpContextAccessor() which allows you to get access to the HttpContext.

services.AddHttpContextAccessor();

services.AddScoped<DbDataProvider>();
services.AddScoped<InMemDataProvider>();
services.AddScoped<IDataProvider>(ctx =>
{
    var contextAccessor = ctx.GetService<IHttpContextAccessor>();
    var httpContext = contextAccessor.HttpContext;

    // Whatever the header is that you are looking for
    if (httpContext.Request.Headers.TryGetValue("Synthetic", out var syth))
    {
        return ctx.GetService<InMemDataProvider>();
    }
    else
    {
        return ctx.GetService<DbDataProvider>();
    }
});
like image 62
Steven Peirce Avatar answered Sep 28 '22 12:09

Steven Peirce