繁体   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