簡體   English   中英

檢測到 UseStartup<tstartup> 在 ASP.NET Core 中被調用</tstartup>

[英]Detect that UseStartup<TStartup> was called in ASP.NET Core

配置 ASP.NET 核心啟動時有這個:

.ConfigureWebHostDefaults(webHostBuilder => {
  //add services here or in Startup.ConfigureServices()   // (1)
  webHostBuilder.UseStartup<Startup>();
})
.ConfigureServices(serviceCollection => {
  //add services here                                     // (2a)
})
.UseMyServices()                                          // (2b)

我必須在 web 主機啟動注冊一些東西。 我可以在位置(2a)或輔助UseMyServices()擴展方法(2b)中執行此操作,這實際上是同一件事。

public static IHostBuilder UseMyServices(this IHostBuilder hostBuilder)
{
  hostBuilder.ConfigureServices((hostBuilderContext, serviceCollection) => {
    //add services here
  };
}

UseServices()內部,我想進行健全性檢查以確保代碼放置在正確的位置。 我可以使用hostBuilderContextserviceCollection來檢測UseStartup<T>()調用是否已經完成?

我查看了serviceCollection以找到一些有趣的東西,例如IStartup ,但沒有找到任何有用的東西。 也許我不是在尋找正確的東西。

摘要:如何檢測UseStartup<TStartup>調用已經完成?

所有服務都將在Startup中調用Configure之前注冊,無論注冊掛鈎是在UseWebHostDefault之前還是之后。 如果這是您的顧慮,那么您無能為力。 請注意,將遵守調用ConfigureServices的順序。

我還沒有真正找到任何“好的”解決方案,但我確實注意到ConfigureWebHost的代碼(因此ConfigureWebHostDefaults )將GenericWebHostService注冊為IHostedService ,所以也許你可以使用它。

這里的問題是服務是internal的,它是一個實現細節,所以不能保證它不會在未來的版本中被更改/刪除/重命名。 無論如何,如果您可以接受這種風險,那么您可以在擴展方法中編寫以下代碼:

public static IHostBuilder UseMyServices(this IHostBuilder hostBuilder)
{
    return hostBuilder
        .ConfigureServices(svc =>
        {
            if (svc.Any(svc => svc.ServiceType == typeof(IHostedService) && svc.ImplementationType.Name == "GenericWebHostService"))
            {
                System.Diagnostics.Debug.WriteLine("After UseWebHostDefault");
            }
            // do your other service registrations
        });
}

這里的問題是,這並沒有專門檢測到調用了UseStartup ,只是檢測到運行了ConfigureWebHostDefaults

--

我發現的另一件事是 UseStartup 向HostBuilderContext屬性( 代碼)添加了一個屬性。 不幸的是,它使用的密鑰是internal class 中的private實例字段(參見此處)。 即使您想冒着執行更改導致運行時錯誤的風險,我也不確定您將如何從這個 class 訪問密鑰。

如果你只是想檢查你的項目中的Startup是否被調用,你可以寫這樣的東西來檢查它的實例是否已經被注冊:

public static IHostBuilder UseMyServices(this IHostBuilder hostBuilder)
{
    return hostBuilder
        .ConfigureServices((ctx, svc) =>
        {
            if (ctx.Properties.Any(p => p.Value?.GetType() == typeof(Startup)))
            {
                System.Diagnostics.Debug.WriteLine("After Startup");
            }
            // do your other service registrations
        });
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM