.NET 6 Web API依赖注入报错:部分服务无法构造问题排查
.NET 6 Web API 依赖注入报错:some Services are not able to be constructed (error while validating the service descriptor)
问题背景
从.NET 5迁移到.NET 6最小宿主模型后,原本运行正常的服务依赖注入逻辑触发服务构造失败错误,.NET 5环境下基于Startup类的注册流程无异常。
相关代码
初始Program.cs代码
using NSBSL.WebAPI.API; var builder = WebApplication.CreateBuilder(args); // 注册控制器服务 builder.Services.AddControllers(); // Swagger/OpenAPI相关配置 builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); builder.Services.RegisterServices(); builder.Configuration.AddJsonFile("appsettings.json", false, false).AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json", true); var app = builder.Build(); // 配置HTTP请求管道 if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); app.UseAuthorization(); app.MapControllers(); app.Run();
服务注册扩展及工厂类代码
- 服务扩展类
public static class ServiceExtensions { public static void RegisterServices(this IServiceCollection services) { new LogicFactory().ConfigureServices(services); } }
- LogicFactory类
public class LogicFactory : IInjectionFactory { public void ConfigureServices(IServiceCollection services) { services.AddSingleton<ISpeedPatternLogic, SpeedPatternLogic>(); new DatasourceFactory().ConfigureServices(services); } }
- DatasourceFactory类
public class DatasourceFactory : IInjectionFactory { public void ConfigureServices(IServiceCollection services) { services.AddSingleton<ISpeedPatternDatasource, SpeedPatternDatasource>(); } }
- 框架通用IInjectionFactory接口定义
public interface IInjectionFactory { void ConfigureServices(IServiceCollection services); }
报错堆栈
at Microsoft.Extensions.DependencyInjection.ServiceProvider..ctor(ICollection`1 serviceDescriptors, ServiceProviderOptions options) at Microsoft.Extensions.DependencyInjection.ServiceCollectionContainerBuilderExtensions.BuildServiceProvider(IServiceCollection services, ServiceProviderOptions options) at Microsoft.Extensions.DependencyInjection.DefaultServiceProviderFactory.CreateServiceProvider(IServiceCollection containerBuilder) at Microsoft.Extensions.Hosting.Internal.ServiceFactoryAdapter`1.CreateServiceProvider(Object containerBuilder) at Microsoft.Extensions.Hosting.HostBuilder.CreateServiceProvider() at Microsoft.Extensions.Hosting.HostBuilder.Build() at Microsoft.AspNetCore.Builder.WebApplicationBuilder.Build() at Program.<Main>$(String[] args)
排查过程
- 首次尝试:直接在Program.cs中将
ISpeedPatternLogic的注册生命周期改为Transient,仍触发相同报错,测试代码如下:
using NSBSL.WebAPI.BusinessLogic.Interfaces.SpeedPattern; using NSBSL.WebAPI.BusinessLogic.Services.SpeedPattern; var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllers(); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); builder.Services.AddTransient<ISpeedPatternLogic, SpeedPatternLogic>();
- 二次排查:核对业务接口与实现类的定义,代码如下:
- ISpeedPatternLogic接口
public interface ISpeedPatternLogic : ILoadable<SpeedPatternModel> { }- ILoadable接口
public interface ILoadable<T> : ILogicBase<T> where T : IModelBase { Task LoadAsync(CancellationToken token); }- SpeedPatternLogic实现类
public class SpeedPatternLogic : ServicesBase<SpeedPatternModel>, ISpeedPatternLogic { private readonly ISpeedPatternDatasource _speedPatternDatasource; public SpeedPatternLogic(INSBSLConfiguration configuration, IMapper mapper, ISpeedPatternDatasource speedPatternDatasource) : base(configuration, mapper) { _speedPatternDatasource = speedPatternDatasource; } public async override Task<IEnumerable<SpeedPatternModel>> GetAllAsync(CancellationToken token) { return Mapper.Map<IEnumerable<SpeedPatternModel>>(await _speedPatternDatasource.GetAllAsync(token)); } public Task LoadAsync(CancellationToken token) { throw new NotImplementedException(); } }
根因定位
查看SpeedPatternLogic的构造函数,共依赖三个服务:INSBSLConfiguration、IMapper、ISpeedPatternDatasource。其中ISpeedPatternDatasource已在DatasourceFactory中完成注册,但框架内置的INSBSLConfiguration服务注册逻辑被遗漏。
框架中原本通过NSBSLConfigurationFactory完成该服务的注册:
public class NSBSLConfigurationFactory : IInjectionFactory { public void ConfigureServices(IServiceCollection services) { services.TryAddSingleton<INSBSLConfiguration, NSBSLConfiguration>(); } }
.NET 5版本下,所有微服务继承的ApiStartup基类会自动调用以下方法完成该配置服务的注册:
private void RegisterNSBSLConfigurationInterfaces(IServiceCollection services) { new NSBSLConfigurationFactory().ConfigureServices(services); }
迁移到.NET 6最小宿主模型后,原Startup基类的自动执行逻辑失效,未手动调用该注册方法,导致DI容器中缺失INSBSLConfiguration服务实例,容器构建时校验服务依赖链失败,抛出构造异常。
修复方案
在Program.cs的服务注册阶段,补充调用NSBSLConfigurationFactory的注册方法,将INSBSLConfiguration注入DI容器即可:
// 补充注册框架配置服务 new NSBSLConfigurationFactory().ConfigureServices(builder.Services); builder.Services.RegisterServices();
内容的提问来源于stack exchange,提问作者user3263515
相关产品推荐
相关产品推荐

