2016-06-07 27 views
0

我有一个使用我的自定义服务注入构造函数的自定义身份验证Middelware。控制器中的作用域服务与中间件中调用的服务不同

MyAuthenticationHandler我打电话给方法MyService设置属性值。

_myService.SetCompany(company); 

公司在认证处理程序中加载并且不为空。但是,当我尝试访问控制器的值时,我发现MyService已被重新初始化。

这是它是如何在Startup.cs

services.AddScoped<IMyService, MyFactory>(); 

回答

3

中间件只初始化一次,当您注册设置。您需要在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承载)。如果通过,下一个中间件(MyMiddleware)将被调用。

换句话说,当您调用MyMiddleware.Invoke()方法时,用户已被认证。

+0

调用GetService不起作用context.RequestServices.GetService ();不允许类型参数。你确定这对RC2有用吗?我还需要在授权后设置公司,在HandleAuthenticateAsync()之后调用Invoke? –

+0

是的,你需要'使用Microsoft.Extensions.DependencyInjection'命名空间声明。或者只是使用非通用版本:'.GetService(typeof(IMyService))',但是在将它分配给一个变量之前,您必须先将它转换为 – Tseng

+0

我不认为您想重写Invoke,I获取有关具有多个公共“调用”方法的错误。(我继承自AuthenticationMiddleware) –

0

您可以直接在Invoke签名中注入该服务。

从官方文档here

如果您必须共享你的中间件和其他类型之间的范围的服务,这些服务为Invoke方法的签名添加。 Invoke方法可以接受由依赖注入填充的其他参数。

所以你的情况:

public async Task Invoke(HttpContext context, IMyService service) 
{ 
    service.SetCompany("My Company"); 

    await _next.Invoke(context); 
} 

会工作。

相关问题