我有一个自定义身份验证Middelware,它使用我在构造函数中注入的自定义服务。
在MyAuthenticationHandler
我正在调用一个设置属性值的MyService
方法。
_myService.SetCompany(company);
公司已加载到身份验证处理程序中,并且不为null。但是,当我尝试从控制器访问该值时,我发现MyService
已重新初始化。
这是在Startup.cs中设置的方式
services.AddScoped<IMyService, MyFactory>();
答案 0 :(得分:4)
中间件仅在您注册时初始化一次。您需要在Invoke方法中解决您的依赖关系。
public class MyMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger _logger;
public MyMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
var service = context.RequestServices.GetService<IMyService>();
service.SetCompany("My Company");
await _next.Invoke(context);
}
}
现在,每个请求都可以正确解析服务,而不是每个应用程序的生命周期。
修改强>
即。为了在授权middelware之后调用您的中间件,您可以在Configure(IAppBuilder app)
方法中执行以下操作:
app.UseCookieAuthentication(options => { ... });
app.UseJwtBearerAuthentication(options => { ... });
app.UseMiddleware<MyMiddleware>(options => { ... });
然后在请求中,首先调用cookie中间件。如果它可以处理该方案并且它失败,则不会执行以下中间件。如果它不能处理该方案,则将调用下一个(jwt bearer)。如果通过,将调用下一个中间件(MyMiddleware
)。
换句话说,当您调用MyMiddleware.Invoke()
方法时,用户已经过身份验证。
答案 1 :(得分:0)
您可以直接在Invoke
签名中注入服务。
来自官方文档here:
如果必须在中间件和其他类型之间共享作用域服务,请将这些服务添加到
Invoke
方法的签名中。Invoke
方法可以接受依赖注入填充的其他参数。
所以在你的情况下:
public async Task Invoke(HttpContext context, IMyService service)
{
service.SetCompany("My Company");
await _next.Invoke(context);
}
会奏效。