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

如何通过ServiceProvider.GetServices获取实现IMyInterface<T>的服务实例?

问题分析与解决方案

先明确你两种写法无效的核心原因:

  • 第一种写法GetServices(typeof(IMyInterface<MyBaseClass>))只能获取**明确注册为IMyInterface<MyBaseClass>**的服务实例,但你实际注册的应该是IMyInterface<DerivedClass>(DerivedClass继承自MyBaseClass)这类封闭泛型服务,所以自然查不到结果——除非你的接口是协变的(定义为IMyInterface<out T>),且注册时用基类接口包装子类实现,但这不是常规注册方式。
  • 第二种写法用了开放泛型IMyInterface<>,但GetServices不支持直接传入开放类型,因为DI容器中注册的都是具体的封闭泛型服务,开放类型无法被实例化,因此报错。

正确实现方式

要获取所有实现IMyInterface<T>且T继承自MyBaseClass的服务实例,需要先筛选符合条件的注册服务类型,再逐个获取实例:

步骤1:筛选目标服务描述符

如果你能访问IServiceCollection(比如在配置服务阶段,或提前保存了服务集合),可以直接遍历筛选:

// 定义目标接口的开放泛型类型
var targetOpenType = typeof(IMyInterface<>);
// 筛选所有符合条件的服务描述符
var matchingServices = services.Where(sd =>
    // 服务类型是泛型类型
    sd.ServiceType.IsGenericType &&
    // 泛型类型定义与目标开放接口一致
    sd.ServiceType.GetGenericTypeDefinition() == targetOpenType &&
    // 泛型参数T是MyBaseClass的子类或自身
    typeof(MyBaseClass).IsAssignableFrom(sd.ServiceType.GetGenericArguments()[0])
).ToList();

步骤2:从ServiceProvider获取实例

拿到筛选后的服务描述符后,逐个调用GetServices获取对应实例:

var allInstances = new List<object>();
foreach (var service in matchingServices)
{
    // 获取该封闭泛型服务的所有实例
    var instances = _serviceProvider.GetServices(service.ServiceType);
    allInstances.AddRange(instances);
}

注意事项

  • 若无法直接访问IServiceCollection(仅能拿到IServiceProvider),不建议通过反射读取容器内部的服务描述(依赖DI容器内部实现,易因版本更新失效),最好在配置服务阶段就将服务集合保存到可访问的位置。
  • 如果你的接口支持协变(定义为public interface IMyInterface<out T> where T : MyBaseClass),可以考虑将实现类注册为IMyInterface<MyBaseClass>,这样第一种写法就能直接获取实例,但这仅适用于不需要区分具体T类型的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 14:55:21