.NET 6 EF项目Program.cs中AutoMapper依赖注入异常求助
异常信息
已触发异常:CLR/System.AggregateException
在Microsoft.Extensions.DependencyInjection.dll中发生未处理的System.AggregateException类型异常:‘部分服务无法构造’
已找到内部异常,可在变量窗口查看$exception获取更多详情。
最内层异常:System.InvalidOperationException : 尝试激活'ApplicationAdmin.EntityFrameworkLayer.Services.ApplicationService'时,无法解析'AutoMapper.Mapper'类型的服务。调用栈信息:
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateArgumentCallSites(Type implementationType, CallSiteChain callSiteChain, ParameterInfo[] parameters, Boolean throwIfCallSiteNotFound)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateConstructorCallSite(ResultCache lifetime, Type serviceType, Type implementationType, CallSiteChain callSiteChain)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateExact(ServiceDescriptor descriptor, Type serviceType, CallSiteChain callSiteChain, Int32 slot)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.GetCallSite(ServiceDescriptor descriptor, CallSiteChain callSiteChain)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.ValidateService(ServiceDescriptor descriptor)
相关代码
Program.cs
using ApplicationAdmin.BusinessLayer.Interfaces; using ApplicationAdmin.BusinessLayer.Services; using ApplicationAdmin.EntityFrameworkLayer.Data.Contexts; using ApplicationAdmin.EntityFrameworkLayer.Interfaces; using ApplicationAdmin.EntityFrameworkLayer.Services; using Microsoft.EntityFrameworkCore; var builder = WebApplication.CreateBuilder(args); ConfigurationManager config = builder.Configuration; // Add services to the container. builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies()); builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); builder.Services.AddDbContext<dbContext>(options => options.UseSqlServer(config.GetConnectionString("default"))); // builder.Services.AddAutoMapper(config => config.AddProfile<ApplicationProfile>()); // builder.Services.AddAutoMapper(config => config.AddProfile<FieldProfile>()); builder.Services.AddScoped<IApplicationService,ApplicationService>(); builder.Services.AddScoped<IFieldService,FieldService>(); builder.Services.AddScoped<IPageService,PageService>(); builder.Services.AddScoped<ISectionService,SectionService>(); builder.Services.AddScoped<ISubsectionService,SubsectionService>(); builder.Services.AddScoped<IApplicationBLService,ApplicationBLService>(); builder.Services.AddScoped<IFieldBLService,FieldBLService>(); var app = builder.Build(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); app.UseAuthorization(); app.MapControllers(); app.Run();
ApplicationService.cs
using ApplicationAdmin.EntityFrameworkLayer.Data.Models; using ApplicationAdmin.EntityFrameworkLayer.Data.Contexts; using ApplicationAdmin.BusinessLayer.DataModels.Application; using ApplicationAdmin.EntityFrameworkLayer.Interfaces; using Microsoft.EntityFrameworkCore; using ApplicationAdmin.Helper; using AutoMapper; namespace ApplicationAdmin.EntityFrameworkLayer.Services; public class ApplicationService : IApplicationService { private dbContext _dbContext; private Mapper _mapper; public ApplicationService (dbContext dbContext, Mapper mapper) { _dbContext = dbContext; _mapper = mapper; } public async Task<List<Application>> Get(GetApplicationRequest request, CancellationToken xlT) { Guid guidApplicationId = Guid.Empty; Guid.TryParse(request.ApplicationId, out guidApplicationId); return await _dbContext.Applications .Where(i => i.ApplicationId == (request.ApplicationId == null ? i.ApplicationId : guidApplicationId) && i.CreatedById == (request.CreatedById ?? i.CreatedById) && i.CreatedOnUtc == (request.CreatedOnUtc ?? i.CreatedOnUtc) && EF.Functions.Like(i.Description,(StringConverter.ConvertToLike(request.Description) ?? i.Description)) && i.IsEnabled == (request.IsEnabled ?? i.IsEnabled) && i.UpdatedById == (request.UpdatedById ?? i.UpdatedById) && i.UpdatedOnUtc == (request.UpdatedOnUtc ?? i.UpdatedOnUtc) ) .ToListAsync(xlT); } public async Task<List<Application>> Post(List<PostApplicationRequest> requests, bool saveNow, CancellationToken xlT) { List<Application> applications = new List<Application>(); foreach(PostApplicationRequest request in requests) { Application application = new Application() { ApplicationId = Guid.NewGuid(), Description = request.Description, IsEnabled = request.IsEnabled, CreatedById = request.CreatedById, CreatedOnUtc = DateTime.UtcNow }; applications.Add(application); } _dbContext.AddRange(applications); if(saveNow) { await _dbContext.SaveChangesAsync(xlT); } return applications; } public async Task<List<Application>> Put(PutApplicationRequest request, bool saveNow, CancellationToken xlT) { List<Application> applications = await Get(_mapper.Map<GetApplicationRequest>(request), xlT); foreach(Application application in applications) { application.Description = (request.Description ?? application.Description); application.IsEnabled = (request.IsEnabled ?? application.IsEnabled); if(_dbContext.ChangeTracker.HasChanges()) { application.UpdatedById = request.UpdatedById; application.UpdatedOnUtc = DateTime.UtcNow; }; }; if(saveNow && _dbContext.ChangeTracker.HasChanges()) { await _dbContext.SaveChangesAsync(xlT); } return applications; } }
IApplicationService.cs
using ApplicationAdmin.EntityFrameworkLayer.Data.Models; using ApplicationAdmin.BusinessLayer.DataModels.Application; namespace ApplicationAdmin.EntityFrameworkLayer.Interfaces; public interface IApplicationService { public Task<List<Application>> Get(GetApplicationRequest request, CancellationToken xlT); public Task<List<Application>> Put(PutApplicationRequest request, bool saveNow, CancellationToken xlT); public Task<List<Application>> Post(List<PostApplicationRequest> requests, bool saveNow, CancellationToken xlT); }
解决方案
1. 修改构造函数依赖类型
AutoMapper在依赖注入容器中注册的是IMapper接口,而非具体的Mapper实现类。修改ApplicationService代码:
// 替换原私有字段类型 private IMapper _mapper; // 替换构造函数参数类型 public ApplicationService (dbContext dbContext, IMapper mapper) { _dbContext = dbContext; _mapper = mapper; }
2. 确保AutoMapper配置正确
如果项目中有自定义的AutoMapper Profile(比如注释掉的ApplicationProfile、FieldProfile),可以合并注册代码:
// 替换原AddAutoMapper调用(二选一即可) // 方式1:指定Profile类型注册 builder.Services.AddAutoMapper(typeof(ApplicationProfile), typeof(FieldProfile)); // 方式2:扫描所有程序集自动发现Profile // builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
完成以上修改后,依赖注入容器就能正确解析IMapper服务,解决服务构造失败的问题。
内容的提问来源于stack exchange,提问作者John Hedge

