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

.NET6注入多实现服务报错:部分服务无法构造的原因排查

问题:.NET6中注入泛型服务时出现构造失败错误

我正在.NET6中注入实现了IDBActionQuery<T>接口的多个服务,已经在Program.cs中添加了以下代码:

builder.Services.AddTransient<IDBActionQuery<Period>, Select<Period>>();

定义的IDBActionQuery<T>接口如下:

public interface IDBActionQuery<T>
{
    Task<List<T>> execute(string query, params (string name, object val)[] pars);
    Task<List<T>> buildAndExecute();
}

对应的Select<T>实现类:

public class Select<T> : DBMotorBase<T>, IDBActionQuery<T>
{
    private readonly IPrintExceptions exceptions;
    private readonly IGetPropertiesService propertiesService;
    private readonly ISQLParametersService sqlParameterService;
    private readonly ISerializeService serializeService;
    private readonly IDeserealizeService<T> deserealizeService;

    public Select(string _connection,
        IPrintExceptions _exceptions, IGetPropertiesService _propertiesService,
        ISQLParametersService _sqlParameterService, ISerializeService _serializeService,
        IDeserealizeService<T> _deserealizeService) : base(_connection)
    {
        exceptions = _exceptions;
        propertiesService = _propertiesService;
        sqlParameterService = _sqlParameterService;
        serializeService = _serializeService;
        deserealizeService = _deserealizeService;
    }

    private string build(string schema = "dbo")
    {
        ...
    }
    public async Task<List<T>> buildAndExecute()
    {
        return await execute(build(),null);
    }

    public async Task<List<T>> execute(string query, params (string name, object val)[] pars)
    {
        ...
    }

    private async Task<List<T>> processCommand(SqlConnection sql, 
        string query, params (string name, object val)[] pars)
    {
        ...
    }
    private async Task<List<T>> processReader(SqlCommand cmd)
    {
      ....
    }
}

运行时出现错误:Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType:,请问错误原因是什么?


错误原因分析

  • 无法解析构造函数中的string _connection参数:依赖注入容器默认只能解析已注册的服务类型,字符串属于基础类型,若未手动配置该参数的注入逻辑,容器无法自动提供对应的连接字符串值。
  • 未注册构造函数中的其他依赖服务:如果IPrintExceptions、IGetPropertiesService、ISQLParametersService、ISerializeService、IDeserealizeService<T>这些接口的实现类未在Program.cs中注册到DI容器,容器无法构造Select<Period>实例。
  • 泛型服务注册不规范:若IDeserealizeService<T>是泛型接口,需以开放泛型方式注册(如AddTransient(typeof(IDeserealizeService<>), typeof(DeserealizeService<>))),仅注册特定泛型参数的版本会导致容器无法匹配对应类型。

解决方向

  1. 处理_connection字符串参数:

    • 从配置文件读取连接字符串,通过工厂方法手动注入:
      var connectionString = builder.Configuration.GetConnectionString("YourConnectionName");
      builder.Services.AddTransient<IDBActionQuery<Period>>(sp => 
          new Select<Period>(
              connectionString,
              sp.GetRequiredService<IPrintExceptions>(),
              sp.GetRequiredService<IGetPropertiesService>(),
              sp.GetRequiredService<ISQLParametersService>(),
              sp.GetRequiredService<ISerializeService>(),
              sp.GetRequiredService<IDeserealizeService<Period>>()
          )
      );
      
    • 或者将连接字符串注册为单例服务:
      builder.Services.AddSingleton(builder.Configuration.GetConnectionString("YourConnectionName"));
      
  2. 注册所有依赖服务:确保构造函数中用到的每个接口都已在DI容器中注册,示例代码:

    builder.Services.AddTransient<IPrintExceptions, PrintExceptions>();
    builder.Services.AddTransient<IGetPropertiesService, GetPropertiesService>();
    builder.Services.AddTransient<ISQLParametersService, SQLParametersService>();
    builder.Services.AddTransient<ISerializeService, SerializeService>();
    builder.Services.AddTransient(typeof(IDeserealizeService<>), typeof(DeserealizeService<>));
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 12:18:19