Asp.net core Asp.Net核心中间件服务依赖于当前用户
我想更改请求范围的服务,或者在自定义中间件层中设置一个 具体地说,我希望能够在Asp.net core Asp.Net核心中间件服务依赖于当前用户,asp.net-core,Asp.net Core,我想更改请求范围的服务,或者在自定义中间件层中设置一个 具体地说,我希望能够在Startup.cs中执行下面的人为示例: public void ConfigureServices(IServiceCollection service) { service.AddScoped<IMyUserDependentService>((provider) => { return new MyService()); }); } public void C
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();
});
}
问题是,这不起作用。myService.UserName在控制器中不是Fred,它是null。我认为IOC容器正在控制器中创建一个新实例,而不是使用中间件中设置的实例 如果我将服务范围更改为Transient,则会记住Fred,但这没有帮助,因为服务依赖于当前用户 总而言之,我需要的是创建/或编辑一个需要当前用户(或其他当前请求变量)的服务,但我无法解决这个问题
提前谢谢 您是否尝试过使用
context.RequestServices
?我刚刚遇到了类似的问题,我遇到了如下错误
InvalidOperationException:无法从根提供程序解析作用域服务“IsOpedService”。
,引发的异常没有很好的文档记录
我是这样解决的:
[Startup.cs]
services.AddScoped<IAnyScopedService, AnyScopedService>();
services.AddSingleton<ISomeOtherSingletonService, SomeOtherSingletonService>();
实际上,中间件只实例化了一次,但调用了很多次。
因此,构造函数采用单例实例,其中invoke方法可以获得作用域内的注入参数
有关的更多详细信息:“我认为IOC容器正在控制器中创建一个新实例,而不是使用中间件中设置的实例。”您可以通过在
IMyUserDependentService
构造函数中放置一个断点来验证这一点,并查看它是否在请求期间多次实例化。有趣的是,对于控制器,每次都会创建一个新服务,但在中间件内部。使用
方法,该服务与前一个请求相同…..wtf?在这种情况下,听起来好像您的中间件在创建“范围”之前就在管道中的某个位置。它是管道中倒数第二个东西,最后一个是app.UseMVC。。?Startup.ConfigureServices肯定会在Startup.Configure(设置中间件的位置)之前被调用。感谢@danludwig的提示!我在app.UseIdentity()
之前有app.Use
,因此我得到context.User.IsSignedIn()的false
,而实际情况并非如此。。
services.AddScoped<IAnyScopedService, AnyScopedService>();
services.AddSingleton<ISomeOtherSingletonService, SomeOtherSingletonService>();
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
}
}