ASP.NET WebHost转Host迁移时依赖注入报错的排查与修复
WebHost迁移至Host模式后依赖注入报错的排查与修复
将ASP.NET Core应用从WebHost启动模式迁移至官方推荐的通用Host模式后,出现UniLocalizer相关的依赖注入报错,原WebHost环境下运行正常。
原WebHost启动代码
private static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>() .UseSerilog((hostingContext, loggerConfiguration) => loggerConfiguration.ReadFrom.Configuration(hostingContext.Configuration)); public static void Main(string[] args) { var host = CreateWebHostBuilder(args).Build(); // start the app. host.Run(); }
修改后的Host启动代码
public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); }) // Add Serilog Logger .UseSerilog((hostingContext, loggerConfiguration) => loggerConfiguration.ReadFrom.Configuration(hostingContext.Configuration)); public static void Main(string[] args) { var host = CreateHostBuilder(args).Build(); // start the app. host.Run(); }
报错信息
System.AggregateException: 'Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: Microsoft.Extensions.Localization.IStringLocalizer Lifetime: Singleton ImplementationType: UniLocalizer.UniLocalizer': No constructor for type 'UniLocalizer.UniLocalizer' can be instantiated using services from the service container and default values.)'
排查与修复方案
- 确认UniLocalizer构造函数依赖:先查看
UniLocalizer.UniLocalizer类的构造函数,明确它需要的依赖服务(比如IStringLocalizerFactory、IOptions<LocalizationOptions>等)。通用Host默认不会自动注册部分WebHost自带的本地化相关服务,这是核心问题。 - 手动注册本地化服务:在
Startup.ConfigureServices中显式添加本地化服务配置,确保UniLocalizer的依赖能被容器解析:public void ConfigureServices(IServiceCollection services) { // 注册基础本地化服务 services.AddLocalization(options => options.ResourcesPath = "Resources"); // 显式注册UniLocalizer,传入所需依赖 services.AddSingleton<IStringLocalizer, UniLocalizer>(sp => { var factory = sp.GetRequiredService<IStringLocalizerFactory>(); var localizationOpts = sp.GetRequiredService<IOptions<LocalizationOptions>>(); return new UniLocalizer(factory, localizationOpts); }); // 其他原有服务注册逻辑... } - 启用本地化中间件:在
Startup.Configure中确保添加本地化中间件,保证相关上下文初始化完成:public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { var supportedCultures = new[] { "en-US", "zh-CN" }; var localizationOptions = new RequestLocalizationOptions() .SetDefaultCulture(supportedCultures[0]) .AddSupportedCultures(supportedCultures) .AddSupportedUICultures(supportedCultures); app.UseRequestLocalization(localizationOptions); // 其他原有中间件逻辑... } - 检查服务生命周期兼容性:报错显示UniLocalizer是单例模式,需确认其依赖的服务是否允许被单例依赖(比如不能将Scoped生命周期服务注入到Singleton服务中)。如果存在这种冲突,要么调整UniLocalizer的生命周期为Scoped,要么通过
IServiceScopeFactory在运行时获取Scoped服务。 - 验证注册顺序:当前代码中Serilog在
ConfigureWebHostDefaults之后注册的顺序是合理的,但如果有其他服务注册顺序问题,也需要逐一排查,避免服务容器初始化时出现依赖缺失。
内容的提问来源于stack exchange,提问作者IT Man
相关产品推荐
相关产品推荐

