生成Identity后ApplicationDbContext与UnitOfWork依赖注入异常求助
添加Identity组件后,项目启动失败,推测是ApplicationDbContext服务未正确注册,导致UnitOfWork激活时无法获取ApplicationDbContext实例。已尝试更新AspNetCore.Identity.EntityFrameworkCore和AspNetCore.EntityFrameworkCore包,但问题仍未解决。
相关代码
ApplicationDbContext
using BookHeaven.Models; using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; namespace BookHeaven.DataAccess; public class ApplicationDbContext : IdentityDbContext { public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { } public DbSet<Category> Categories { get; set; } public DbSet<CoverType> CoverTypes { get; set; } public DbSet<Product> Products { get; set; } }
Program.cs
using BookHeaven.DataAccess; using BookHeaven.DataAccess.Repository; using BookHeaven.DataAccess.Repository.IRepository; using Microsoft.AspNetCore.Builder; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.AspNetCore.Identity; var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllersWithViews(); builder.Services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer( builder.Configuration.GetConnectionString("DefaultConnection") )); builder.Services.AddDefaultIdentity<IdentityUser>() .AddEntityFrameworkStores<ApplicationDbContext>(); builder.Services.AddScoped<IUnitOfWork, UnitOfWork>(); var app = builder.Build(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Home/Error"); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.MapControllerRoute( name: "default", pattern: "{area=Customer}/{controller=Home}/{action=Index}/{id?}"); app.Run();
UnitOfWork.cs
using BookHeaven.DataAccess.Repository.IRepository; using BookHeaven.DataAccess.Repository; using BookHeaven.DataAccess; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace BookHeaven.DataAccess.Repository { public class UnitOfWork : IUnitOfWork { private ApplicationDbContext _db; public UnitOfWork(ApplicationDbContext db) { _db = db; Category = new CategoryRepository(_db); CoverType = new CoverTypeRepository(_db); Product = new ProductRepository(_db); } public ICategoryRepository Category { get; private set; } public ICoverTypeRepository CoverType { get; private set; } public IProductRepository Product { get; private set; } public void Save() { _db.SaveChanges(); } } }
CategoryRepository.cs
using BookHeaven.DataAccess.Repository.IRepository; using BookHeaven.Models; using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace BookHeaven.DataAccess.Repository { public class CategoryRepository : Repository<Category>, ICategoryRepository { private readonly ApplicationDbContext _db; public CategoryRepository(ApplicationDbContext db) : base(db) { _db = db; } public void Update(Category entity) { _db.Categories.Update(entity); } } }
IUnitOfWork.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace BookHeaven.DataAccess.Repository.IRepository { public interface IUnitOfWork { public ICategoryRepository Category { get; } public ICoverTypeRepository CoverType { get; } public IProductRepository Product { get; } void Save(); } }
Repository.cs
using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; using System.Threading.Tasks; using BookHeaven.DataAccess.Repository.IRepository; using Microsoft.EntityFrameworkCore; using static Microsoft.EntityFrameworkCore.DbLoggerCategory; namespace BookHeaven.DataAccess.Repository { public class Repository<T> : IRepository<T> where T: class { private readonly ApplicationDbContext _db; internal DbSet<T> dbSet; public Repository(ApplicationDbContext db) { _db = db; dbSet = _db.Set<T>(); } public void Add(T entity) { dbSet.Add(entity); } public IEnumerable<T> GetAll(string? includeProperties = null) { IQueryable<T> query = dbSet; if (includeProperties != null) { foreach (var prop in includeProperties.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) { query = query.Include(prop); } } return query.ToList(); } public void Remove(T entity) { dbSet.Remove(entity); } public void RemoveRange(IEnumerable<T> entity) { dbSet.RemoveRange(entity); } public T GetFirstOrDefault(Expression<Func<T, bool>> filterExpression, string? includeProperties = null) { IQueryable<T> query = dbSet; query = query.Where(filterExpression); if(includeProperties != null) { foreach(var prop in includeProperties.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) { query = query.Include(prop); } } return query.FirstOrDefault(); } } }
错误信息
System.AggregateException HResult=0x80131500 消息=某些服务无法构造(验证服务描述符“ServiceType: BookHeaven.DataAccess.Repository.IRepository.IUnitOfWork Lifetime: Scoped ImplementationType: BookHeaven.DataAccess.Repository.UnitOfWork”时出错:尝试激活“BookHeaven.DataAccess.Repository.UnitOfWork”时,无法解析类型“BookHeaven.DataAccess.ApplicationDbContext”的服务。) 源=Microsoft.Extensions.DependencyInjection 堆栈跟踪: 在 Microsoft.Extensions.DependencyInjection.ServiceProvider..ctor(ICollection`1 serviceDescriptors, ServiceProviderOptions options) 在 Microsoft.Extensions.DependencyInjection.ServiceCollectionContainerBuilderExtensions.BuildServiceProvider(IServiceCollection services, ServiceProviderOptions options) 在 Microsoft.Extensions.Hosting.HostApplicationBuilder.Build() 在 Microsoft.AspNetCore.Builder.WebApplicationBuilder.Build() 在 Program.$(String[] args) 位置 C:\C#\ASP.NET\BookHeaven\BookHeavenWeb\Program.cs:行 21
此异常最初是在此调用堆栈中引发的:[外部代码]
内部异常 1:
InvalidOperationException: 验证服务描述符“ServiceType: BookHeaven.DataAccess.Repository.IRepository.IUnitOfWork Lifetime: Scoped ImplementationType: BookHeaven.DataAccess.Repository.UnitOfWork”时出错:尝试激活“BookHeaven.DataAccess.Repository.UnitOfWork”时,无法解析类型“BookHeaven.DataAccess.ApplicationDbContext”的服务。
内部异常 2:
InvalidOperationException: 尝试激活“BookHeaven.DataAccess.Repository.UnitOfWork”时,无法解析类型“BookHeaven.DataAccess.ApplicationDbContext”的服务。
修复方案
1. 确认连接字符串配置正确
检查Web项目的appsettings.json文件,确保存在DefaultConnection节点,且连接字符串格式正确,指向可访问的SQL Server实例:
{ "ConnectionStrings": { "DefaultConnection": "Server=你的SQL服务器地址;Database=BookHeaven;Trusted_Connection=True;TrustServerCertificate=True;" } }
2. 统一所有EF Core相关包版本
确保BookHeaven.DataAccess和BookHeavenWeb项目中,以下NuGet包的版本完全一致:
- Microsoft.EntityFrameworkCore
- Microsoft.EntityFrameworkCore.SqlServer
- Microsoft.AspNetCore.Identity.EntityFrameworkCore
版本不一致会导致依赖注入容器无法正确识别ApplicationDbContext类型。
3. 验证服务注册顺序
需确保AddDbContext<ApplicationDbContext>在AddScoped<IUnitOfWork, UnitOfWork>之前执行。依赖注入容器需要先注册ApplicationDbContext,才能将其注入到UnitOfWork中。
4. 检查项目引用
确认BookHeavenWeb项目已正确引用BookHeaven.DataAccess项目。若未引用,DI容器无法找到ApplicationDbContext类型。
5. 显式指定服务生命周期
尝试显式指定ApplicationDbContext的生命周期为Scoped(与UnitOfWork一致),避免默认配置异常:
builder.Services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")), ServiceLifetime.Scoped);
6. 清理并重建解决方案
项目缓存可能导致类型无法被DI容器识别,执行以下步骤:
- 在Visual Studio中选择菜单「生成」→「清理解决方案」
- 再选择「生成」→「重新生成解决方案」
- 重新启动项目
内容的提问来源于stack exchange,提问作者swaggoo

