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

C#中DI容器注入带构造参数的泛型接口问题

泛型服务带构造参数的DI注册方案

问题代码

public interface A<T> { T GetValue(); }

public class B<T> : A<T> 
{ 
    private readonly string _key;

    public B(string key)
    {
        _key = key;
    }

    public T GetValue()
    {
        return default(T);
    }
}

直接使用services.AddScoped(typeof(A<>), typeof(B<>))注册会报错,原因是DI容器无法自动解析B<T>构造函数中的string key参数。以下是几种可行的注册方案:


方案1:使用固定key注册开放泛型

如果所有B<T>实例共用同一个固定key,可通过工厂委托创建实例:

services.AddScoped(typeof(A<>), (provider, serviceType) =>
{
    // 获取当前要解析的封闭泛型类型的参数(比如A<string>的参数是string)
    var genericArgs = serviceType.GetGenericArguments();
    // 创建对应的B<T>封闭泛型类型
    var bImplementationType = typeof(B<>).MakeGenericType(genericArgs);
    // 替换为你的固定key值
    return Activator.CreateInstance(bImplementationType, "your-fixed-key") as object;
});

方案2:从其他服务动态获取key

如果key需要从DI容器内的其他服务(比如配置服务)获取,可在工厂委托中解析依赖:

// 先注册提供key的服务(示例)
services.AddScoped<IConfigService, ConfigService>();

services.AddScoped(typeof(A<>), (provider, serviceType) =>
{
    var configService = provider.GetRequiredService<IConfigService>();
    // 根据泛型参数动态获取对应key(示例逻辑)
    string targetKey = configService.GetKeyForType(serviceType.GetGenericArguments()[0]);

    var genericArgs = serviceType.GetGenericArguments();
    var bImplementationType = typeof(B<>).MakeGenericType(genericArgs);
    return Activator.CreateInstance(bImplementationType, targetKey) as object;
});

方案3:为特定泛型版本单独注册

如果只需要为特定的T类型注册对应的服务,可直接指定封闭泛型类型并传入key:

// 为A<string>注册B<string>,指定专属key
services.AddScoped<A<string>>(_ => new B<string>("string-type-key"));

// 为A<int>注册B<int>,指定专属key
services.AddScoped<A<int>>(_ => new B<int>("int-type-key"));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 10:40:03