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

生成Identity后ApplicationDbContext与UnitOfWork依赖注入异常求助

问题:添加Identity后ASP.NET Core项目无法启动,UnitOfWork无法获取ApplicationDbContext实例

添加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容器识别,执行以下步骤:

  1. 在Visual Studio中选择菜单「生成」→「清理解决方案」
  2. 再选择「生成」→「重新生成解决方案」
  3. 重新启动项目

内容的提问来源于stack exchange,提问作者swaggoo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 19:26:59