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
相关产品推荐
相关产品推荐

