DI容器注入数据访问层时出现构造函数歧义异常问题
依赖注入激活
CarRepo时出现构造函数歧义错误 执行app.Build()时抛出异常,提示无法激活DAL.Repos.CarRepo类型,具体错误信息如下:
无法激活类型“DAL.Repos.CarRepo”。以下构造函数存在歧义: Void .ctor(DAL.EfMainStructures.ApplicationContext) Void .ctor(Microsoft.EntityFrameworkCore.DbContextOptions`1[DAL.EfMainStructures.ApplicationContext])
相关代码片段
Program.cs 依赖配置
var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllersWithViews(); // Add services to the container. var connectionString = builder.Configuration.GetConnectionString("Default"); builder.Services.AddDbContextPool<ApplicationContext>(options => options.UseNpgsql(connectionString,sqlOp => sqlOp.EnableRetryOnFailure())); builder.Services.AddScoped<ICarRepo,CarRepo>(); /*builder.Services.AddScoped<ICustomerRepo,CustomerRepo>(); builder.Services.AddScoped<ICreditRiskRepo,CreditRiskRepo>(); builder.Services.AddScoped<IMakeRepo,MakeRepo>(); builder.Services.AddScoped<IOrderRepo,OrderRepo>();*/ /*builder.Services.AddScoped(typeof(IAppLogging<>),typeof(AppLogging<>)); builder.Host.ConfigureSerilog();*/ var app = builder.Build();
ApplicationContext 定义
public partial class ApplicationContext : DbContext { public ApplicationContext(DbContextOptions<ApplicationContext> options) : base(options) { } public virtual DbSet<CreditRisk>? CreditRisks { get; set; } public virtual DbSet<Customer>? Customers { get; set; } public virtual DbSet<Make>? Makes { get; set; } public virtual DbSet<Car>? Cars { get; set; } public virtual DbSet<Order>? Orders { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { OnModelCreatingPartial(modelBuilder); } partial void OnModelCreatingPartial(ModelBuilder modelBuilder); }
解决方案
问题核心是CarRepo类存在两个可被依赖注入容器解析的公共构造函数,容器无法自动判断应该选择哪一个注入依赖。
具体解决步骤
检查并清理
CarRepo的构造函数
打开CarRepo类,确认是否存在以下两个构造函数:public CarRepo(ApplicationContext context) { ... } public CarRepo(DbContextOptions<ApplicationContext> options) { ... }删除其中一个冗余的构造函数即可。
推荐保留的构造函数类型
结合你在Program.cs中使用AddDbContextPool注册ApplicationContext的方式,推荐保留接受ApplicationContext实例的构造函数:// 保留该构造函数,移除另一个 public CarRepo(ApplicationContext context) { _context = context; }这种方式可以直接复用容器管理的
ApplicationContext池化实例,符合依赖注入的最佳实践。备选方案:指定优先构造函数
如果因特殊原因必须保留两个构造函数,可以给希望容器优先使用的构造函数添加[ActivatorUtilitiesConstructor]特性,明确告知DI容器选择逻辑:[ActivatorUtilitiesConstructor] public CarRepo(ApplicationContext context) { _context = context; }
内容的提问来源于stack exchange,提问作者Divergent7
相关产品推荐
相关产品推荐

