ASP.NET Core如何在非Development环境启用服务生命周期验证
解决方案
行为差异原因
Development环境下默认开启了依赖注入容器的作用域校验与构建校验,其余自定义环境默认关闭这两个校验开关,因此不会抛出生命周期配置错误。
为自定义环境开启生命周期校验
直接修改Program.cs的主机构建逻辑,通过UseDefaultServiceProvider手动指定需要开启校验的环境即可,示例代码如下:
using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Hosting; using WebApplication1; var builder = Host.CreateDefaultBuilder(args) .ConfigureHostConfiguration(configHost => { }) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); webBuilder.UseDefaultServiceProvider((hostContext, options) => { // 可自定义判断逻辑,比如所有非生产环境都开启,或单独匹配Local等自定义环境名 var enableValidation = hostContext.HostingEnvironment.IsEnvironment("Local") || hostContext.HostingEnvironment.IsDevelopment(); // 开启作用域校验,检测单例服务注入作用域服务的错误 options.ValidateScopes = enableValidation; // 开启启动时全量校验,应用启动阶段就遍历检查所有已注册服务的依赖关系,无需等待服务首次被调用才报错 options.ValidateOnBuild = enableValidation; }); }); builder.Build().Run();
注意:上述两个校验开关会带来明显的性能损耗,禁止在生产环境开启,仅用于本地开发、联调等开发类场景。
校验逻辑源码位置
该生命周期校验逻辑不属于ASP.NET Core MVC层,是底层依赖注入与主机层的内置功能:
- 环境判断、默认开启校验的逻辑在
Microsoft.Extensions.Hosting类库的HostingHostBuilderExtensions.cs文件中,CreateDefaultBuilder方法内部会判断当前环境如果是Development,就自动将ValidateScopes、ValidateOnBuild两个属性设为true。 - 具体的生命周期合规性检测逻辑在
Microsoft.Extensions.DependencyInjection类库的ServiceProvider实现中,当检测到单例服务依赖生命周期更短的作用域/瞬态服务时,就会抛出你看到的cannot consume scoped service...类型异常。
内容的提问来源于stack exchange,提问作者Danioss
相关产品推荐
相关产品推荐

