2016-06-07 28 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); 
} 

會工作。

相關問題