Q:

ASP.NET Core Middleware Passing Parameters to Controllers

I am using ASP.NET Core Web API, where I have Multiple independent web api projects. Before executing any of the controllers' actions, I have to check if the the logged in user is already impersonating other user (which i can get from DB) and can pass the impersonated user Id to the actions.
Since this is a piece of code that gonna be reused, I thought I can use a middleware so:

I can get the initial user login from request header
Get the impesonated User Id if any
Inject that ID in the request pipeline to make it available to the api being called

public class GetImpersonatorMiddleware
{
    private readonly RequestDelegate _next;
    private IImpersonatorRepo _repo { get; set; }

    public GetImpersonatorMiddleware(RequestDelegate next, IImpersonatorRepo imperRepo)
    {
        _next = next;
        _repo = imperRepo;
    }
    public async Task Invoke(HttpContext context)
    {
        //get user id from identity Token
        var userId = 1;

        int impersonatedUserID = _repo.GetImpesonator(userId);

        //how to pass the impersonatedUserID so it can be picked up from controllers
        if (impersonatedUserID > 0 )
            context.Request.Headers.Add("impers_id", impersonatedUserID.ToString());

        await _next.Invoke(context);
    }
}

I found this Question, but that didn't address what I am looking for.
How can I pass a parameter and make it available in the request pipeline? Is it Ok to pass it in the header or there is more elegant way to do this?

A:

You can use HttpContext.Items to pass arbitrary values inside the pipeline:
context.Items["some"] = "value";

A:

A better solution would be to use a scoped service. Take a look at this: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?tabs=aspnetcore2x#per-request-dependencies
Your code should look like:
public class MyMiddleware
{
    private readonly RequestDelegate _next;

    public MyMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext httpContext, IImpersonatorRepo imperRepo)
    {
        imperRepo.MyProperty = 1000;
        await _next(httpContext);
    }
}

And then register your ImpersonatorRepo as:
services.AddScoped<IImpersonatorRepo, ImpersonatorRepo>()

