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

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类存在两个可被依赖注入容器解析的公共构造函数,容器无法自动判断应该选择哪一个注入依赖。

具体解决步骤

  1. 检查并清理CarRepo的构造函数
    打开CarRepo类,确认是否存在以下两个构造函数:

    public CarRepo(ApplicationContext context) { ... }
    public CarRepo(DbContextOptions<ApplicationContext> options) { ... }
    

    删除其中一个冗余的构造函数即可。

  2. 推荐保留的构造函数类型
    结合你在Program.cs中使用AddDbContextPool注册ApplicationContext的方式,推荐保留接受ApplicationContext实例的构造函数:

    // 保留该构造函数,移除另一个
    public CarRepo(ApplicationContext context)
    {
        _context = context;
    }
    

    这种方式可以直接复用容器管理的ApplicationContext池化实例,符合依赖注入的最佳实践。

  3. 备选方案:指定优先构造函数
    如果因特殊原因必须保留两个构造函数,可以给希望容器优先使用的构造函数添加[ActivatorUtilitiesConstructor]特性,明确告知DI容器选择逻辑:

    [ActivatorUtilitiesConstructor]
    public CarRepo(ApplicationContext context)
    {
        _context = context;
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 11:05:21