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

C#中如何注册带部分具体参数的开放泛型类型?

在C#中注册开放泛型依赖注入并指定部分具体参数

你遇到的核心问题是:C#不允许直接定义RepoBase<,,MyDbContext>这类混合开放/闭合泛型参数的类型——开放泛型要么所有参数都未指定(用逗号占位),要么全部指定为具体类型,因此常规注册方式无法满足需求。以下是两种可行的解决方案:

方案1:创建中间继承类(推荐)

通过定义一个继承自RepoBase<T,TKey,MyDbContext>的开放泛型类,固定第三个泛型参数为MyDbContext,使其与IRepo<T,TKey>的泛型参数匹配:

// 中间类:固定第三个泛型参数为MyDbContext
public class MyDbRepoBase<T, TKey> : RepoBase<T, TKey, MyDbContext> 
    where T : class
{
    // 传递构造函数参数给基类
    public MyDbRepoBase(MyDbContext dbContext) : base(dbContext)
    {
    }
}

随后在DI容器中正常注册开放泛型:

services.AddScoped(typeof(IRepo<,>), typeof(MyDbRepoBase<,>));

这种方式代码简洁、可读性高,且符合DI容器的常规注册逻辑,无反射开销。

方案2:使用工厂委托手动创建实例

若不想新增中间类,可通过DI的工厂重载,手动构造目标泛型类型并创建实例:

services.AddScoped(typeof(IRepo<,>), (serviceProvider, targetType) =>
{
    // 获取当前要创建的IRepo具体类型的泛型参数(例如T=User,TKey=int)
    var genericArgs = targetType.GetGenericArguments();
    var tType = genericArgs[0];
    var tKeyType = genericArgs[1];

    // 构造RepoBase<T, TKey, MyDbContext>的具体封闭泛型类型
    var repoConcreteType = typeof(RepoBase<,,>).MakeGenericType(tType, tKeyType, typeof(MyDbContext));

    // 自动从容器中解析构造函数所需参数(如MyDbContext)并创建实例
    return ActivatorUtilities.CreateInstance(serviceProvider, repoConcreteType);
});

这种方式无需新增类,但涉及反射操作,可读性稍弱,适合不想额外增加类的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 00:58:26