.NET 6 Minimal API集成Asp.net Core Identity执行首次迁移报错问询
错误根本原因
你的DatabaseDBContext实现了IEndpointDefinition接口,在AddEndpointDefinitions方法扫描所有实现该接口的类时,使用了Activator.CreateInstance方法反射创建实例,该方法默认需要调用类的无参构造函数。但你的DatabaseDBContext仅定义了带DbContextOptions<DatabaseDBContext>参数的构造函数,没有无参构造函数,因此触发了MissingMethodException异常。
解决方案
方案1:拆分职责,避免DbContext实现业务接口(推荐)
DbContext的核心职责是数据访问,不应该承载服务注册、中间件注册的逻辑,你可以单独创建一个类实现IEndpointDefinition接口,把相关逻辑迁移过去:
// 新增独立的端点定义类 public class IdentityEndpointDefinition : IEndpointDefinition { public void DefineEndpoints(WebApplication app) { app.UseAuthentication(); } public void DefineServices(IServiceCollection services) { // 注册DbContext services.AddDbContext<DatabaseDBContext>(options => { var config = services.BuildServiceProvider().GetRequiredService<IConfiguration>(); options.UseSqlServer(config.GetConnectionString("AppDb")); }); services.AddIdentity<IdentityUser, IdentityRole>().AddEntityFrameworkStores<DatabaseDBContext>(); } }
修改DatabaseDBContext,移除IEndpointDefinition接口实现和冗余逻辑:
public class DatabaseDBContext : IdentityDbContext { public DatabaseDBContext(DbContextOptions<DatabaseDBContext> options) : base(options) { } protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); } }
该方案同时解决了DbContext和端点定义实例生命周期不匹配的潜在问题,符合单一职责设计原则。
方案2:修改实例创建逻辑,支持带参构造
如果你不想拆分现有逻辑,可以将AddEndpointDefinitions方法中的Activator.CreateInstance替换为ActivatorUtilities.CreateInstance,该方法会从服务容器中自动解析构造函数所需的参数,无需无参构造函数:
修改EndpointDefinition.cs中的对应代码:
endpointDefinitions.AddRange( marker.Assembly.ExportedTypes .Where(x => typeof(IEndpointDefinition).IsAssignableFrom(x) && !x.IsInterface && !x.IsAbstract) // 替换原有实例创建逻辑 .Select(x => ActivatorUtilities.CreateInstance(services, x)) .Cast<IEndpointDefinition>());
小提示:你提到的配置文件名应为
appsettings.json,而非appsetting.js,文件名错误会导致连接字符串读取失败。
内容的提问来源于stack exchange,提问作者DevdotHamza

