.NET MVC应用启动触发System.AggregateException问题求助
问题现象
开发.NET MVC应用时,dotnet build命令可正常构建解决方案,但启动应用通过Swagger访问API时,在Program.cs的var app = builder.Build();代码处抛出System.AggregateException,导致运行失败。
异常核心提示:
'System.AggregateException' in Microsoft.Extensions.DependencyInjection.dll,验证服务描述符时出错:ServiceType: Example.Services.Interfaces.IApplicantService Lifetime: Transient ImplementationType: Example.Services.ApplicantService:尝试激活ApplicantService时无法解析Example.Core.Interfaces.IUnitOfWork类型的服务
所有通过AddTransient注册的业务服务均触发同类错误。
相关代码片段
Program.cs核心代码
using Example.Api.Data; using Example.Services; using Example.Services.Interfaces; using Example.Core; using Example.Core.Interfaces; using Example.Core.Repositories; using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; using Microsoft.OpenApi.Models; using Swashbuckle.AspNetCore.Swagger; using Swashbuckle.AspNetCore.SwaggerUI; var builder = WebApplication.CreateBuilder(args); // 服务注册 var connectionString = builder.Configuration.GetConnectionString("DefaultConnection"); builder.Services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(connectionString)); builder.Services.AddDatabaseDeveloperPageExceptionFilter(); builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true) .AddEntityFrameworkStores<ApplicationDbContext>(); builder.Services.AddAutoMapper(typeof(StartupBase)); builder.Services.AddControllersWithViews(); builder.Services.AddScoped<IUnitOfWork, UnitOfWork>(); builder.Services.AddTransient<IApplicantService, ApplicantService>(); builder.Services.AddTransient<IApplicantSurveyChoicesService, ApplicantSurveyChoicesService>(); builder.Services.AddTransient<IApplicantSurveyService, ApplicantSurveyService>(); builder.Services.AddTransient<IChoiceService,ChoiceService>(); builder.Services.AddSwaggerGen(); var app = builder.Build(); // 异常触发位置 // 请求管道配置(省略) app.Run();
IUnitOfWork接口
public interface IUnitOfWork : IDisposable { IApplicantRepository Applicants { get; } IApplicantSurveyChoicesRepository ApplicantSurveyChoices { get; } IApplicantSurveyRepository ApplicantSurveys { get; } IChoiceRepository Choices{ get; } Task<int> CommitAsync(); }
UnitOfWork实现类
public UnitOfWork(DbContext context) { this._context = context; } public UnitOfWork(DbContext context, DbContext context1, IHostingEnvironment _environment, IHttpContextAccessor httpContextAccessor) { this._context = context; this._environment = _environment; _httpContextAccessor = httpContextAccessor; } public IApplicantRepository Applicants => _applicantRepository = _applicantRepository ?? new ApplicantRepository(_context, Config, _httpContextAccessor); public IApplicantSurveyChoicesRepository ApplicantSurveyChoices => _applicantsurveychoicesrepository = _applicantsurveychoicesrepository ?? new ApplicantSurveyChoicesRepository(_context, Config, _httpContextAccessor); public IApplicantSurveyRepository ApplicantSurveys => _applicantsurveysrepository = _applicantsurveysrepository ?? new ApplicantSurveyRepository(_context, Config, _httpContextAccessor); public IChoiceRepository Choices => _choicerepository = _choicerepository ?? new ChoiceRepository(_context, Config, _httpContextAccessor); public async Task<int> CommitAsync() { return await _context.SaveChangesAsync(); } public void Dispose() { _context.Dispose(); }
错误原因分析
UnitOfWork构造函数歧义与依赖缺失:
- DI容器默认会选择参数最多的构造函数,而你提供的多参数构造函数需要
IHostingEnvironment、IHttpContextAccessor等服务,但这些服务未在Program.cs中注册。 - 构造函数中使用基类
DbContext,但你仅注册了ApplicationDbContext,DI无法自动匹配。
- DI容器默认会选择参数最多的构造函数,而你提供的多参数构造函数需要
Repository实例化方式错误:
在UnitOfWork中直接通过new创建Repository实例,而非依赖DI注入,导致Repository所需的Config等服务无法被解析。
解决步骤
1. 修正UnitOfWork构造函数与依赖注册
- 统一构造函数,明确使用
ApplicationDbContext,并注入所有必需依赖:private readonly ApplicationDbContext _context; private readonly IWebHostEnvironment _environment; private readonly IHttpContextAccessor _httpContextAccessor; private readonly IConfig _config; // 假设Config对应IConfig接口 public UnitOfWork(ApplicationDbContext context, IWebHostEnvironment environment, IHttpContextAccessor httpContextAccessor, IConfig config) { _context = context; _environment = environment; _httpContextAccessor = httpContextAccessor; _config = config; } - 在
Program.cs中补充缺失的服务注册:// 注册HttpContext访问器 builder.Services.AddHttpContextAccessor(); // 注册配置服务(根据你的Config实现调整,这里以绑定配置节为例) builder.Services.Configure<Config>(builder.Configuration.GetSection("YourConfigSectionName")); // 若为接口实现类注册: // builder.Services.AddScoped<IConfig, ConfigImplementation>();
2. 改用DI注入Repository
- 修改
UnitOfWork,通过构造函数注入所有Repository,避免直接new:public class UnitOfWork : IUnitOfWork { public IApplicantRepository Applicants { get; } public IApplicantSurveyChoicesRepository ApplicantSurveyChoices { get; } public IApplicantSurveyRepository ApplicantSurveys { get; } public IChoiceRepository Choices { get; } private readonly ApplicationDbContext _context; public UnitOfWork(ApplicationDbContext context, IApplicantRepository applicantRepository, IApplicantSurveyChoicesRepository applicantSurveyChoicesRepository, IApplicantSurveyRepository applicantSurveyRepository, IChoiceRepository choiceRepository) { _context = context; Applicants = applicantRepository; ApplicantSurveyChoices = applicantSurveyChoicesRepository; ApplicantSurveys = applicantSurveyRepository; Choices = choiceRepository; } public async Task<int> CommitAsync() { return await _context.SaveChangesAsync(); } public void Dispose() { _context.Dispose(); } } - 在
Program.cs中注册所有Repository:builder.Services.AddScoped<IApplicantRepository, ApplicantRepository>(); builder.Services.AddScoped<IApplicantSurveyChoicesRepository, ApplicantSurveyChoicesRepository>(); builder.Services.AddScoped<IApplicantSurveyRepository, ApplicantSurveyRepository>(); builder.Services.AddScoped<IChoiceRepository, ChoiceRepository>();
3. 调整服务注册顺序
确保所有依赖服务(Repository、IHttpContextAccessor等)在IUnitOfWork和业务服务之前完成注册。
4. 验证Repository依赖
检查每个Repository的构造函数,确保其所需的所有服务(如IConfig、IHttpContextAccessor)均已在DI容器中注册。
内容的提问来源于stack exchange,提问作者Kamilah

