You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET MVC应用启动触发System.AggregateException问题求助

.NET MVC应用启动依赖注入失败排查与解决

问题现象

开发.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();
}

错误原因分析

  1. UnitOfWork构造函数歧义与依赖缺失:

    • DI容器默认会选择参数最多的构造函数,而你提供的多参数构造函数需要IHostingEnvironment、IHttpContextAccessor等服务,但这些服务未在Program.cs中注册。
    • 构造函数中使用基类DbContext,但你仅注册了ApplicationDbContext,DI无法自动匹配。
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 23:30:48