Asp.Net Core Middleware service dependent on current user

I would like to either change the service with a limited request, or install it at the user level of the middleware.

In particular, I want to be able to do something like the far-fetched example below in Startup.cs :

 public void ConfigureServices(IServiceCollection service) { service.AddScoped<IMyUserDependentService>((provider) => { return new MyService()); }); } public void Configure(...) { //other config removed app.Use(async (context, next) => { var myService = context.ApplicationServices.GetService<IMyUserDependentService>(); myService.SetUser(context.User.Identity.Name);//Name is Fred next.Invoke(); }); } 

Then in the controller, do the following:

 public class HomeController: Controller { public HomeController(IMyUserDependentService myService) { //myService.UserName should equal Fred } } 

The problem is that this does not work. myService.UserName is not Fred in the controller, this is null. I think the IOC container creates a new instance in the controller and does not use one set in the middleware.

If I changed the scope of the service to Transient, Fred will be remembered, but it will not help, because the service depends on who the current user is.

To repeat, I need to create / or edit a service that requires the current user (or other current request variables), but I cannot handle this.

Thanks in advance!

+6
source share
2 answers

Have you tried using context.RequestServices ?

+4
source

I just ran into a similar problem, I received an error message like InvalidOperationException: Cannot resolve scoped service 'IScopedService' from root provider. The exception was very poorly documented.

Here's how I solved it:

[Startup.cs]

 services.AddScoped<IAnyScopedService, AnyScopedService>(); services.AddSingleton<ISomeOtherSingletonService, SomeOtherSingletonService>(); 

[MyMiddleware.cs]

 public sealed class MyMiddleware { private readonly RequestDelegate _next; private readonly ISomeOtherSingletonService _Svc; public MyMiddleware( RequestDelegate next, ISomeOtherSingletonService svc) { _next = next; _Svc = svc; } public async Task Invoke(HttpContext context, IAnyScopedService scopedService) { // Some work with scoped service } } 

Indeed, Middleware is created only once, but is called many times. Consequently, the constructor accepts singleton instances where the invoke method can retrieve the entered scope parameters.

More on the post of Mark Winche

0
source

Source: https://habr.com/ru/post/1242886/


All Articles