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

.NET无法创建开放类型数组:如何获取泛型接口所有实现?

获取IReadableEntity所有实现的解决方案

你的错误原因是:开放泛型类型(如IReadableEntity<>)无法被实例化为数组或集合,DI容器只能处理闭合泛型(即指定了具体T的类型,如IReadableEntity<Customer>)的服务注册与解析。

要获取所有IReadableEntity<T>的实现(无论T是什么类型),可以通过以下两种方式实现:

方式一:从已注册服务中筛选实例

直接遍历DI容器中所有已注册的服务,筛选出实现了任意IReadableEntity<T>的实例:

using (var scope = app.Services.CreateScope())
{
    var provider = scope.ServiceProvider;
    // 获取所有已注册的服务实例
    var allServices = provider.GetServices<object>();
    
    // 筛选出实现了IReadableEntity<T>的实例
    var readableEntities = allServices
        .Where(service => 
            service.GetType().GetInterfaces()
                .Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IReadableEntity<>)))
        .ToList();
}

方式二:遍历服务描述获取实现类型

如果只需要获取实现类型(而非实例),可以直接遍历服务注册描述:

using (var scope = app.Services.CreateScope())
{
    var provider = scope.ServiceProvider;
    // 获取所有服务注册描述
    var serviceDescriptors = provider.GetRequiredService<IServiceCollection>();
    
    // 筛选出服务类型为IReadableEntity<T>的实现类型
    var readableEntityImplTypes = serviceDescriptors
        .Where(desc => 
            desc.ServiceType.IsGenericType && 
            desc.ServiceType.GetGenericTypeDefinition() == typeof(IReadableEntity<>))
        .Select(desc => desc.ImplementationType)
        .ToList();

    // 按需实例化这些类型
    var instances = readableEntityImplTypes
        .Select(type => provider.GetService(type))
        .Where(instance => instance != null)
        .ToList();
}

前置要求:正确注册所有闭合泛型实现

确保你已经在DI容器中注册了所有IReadableEntity<T>的闭合泛型实现,例如:

// 注册具体的实现类
services.AddTransient<IReadableEntity<Customer>, CustomerReadableEntity>();
services.AddTransient<IReadableEntity<Order>, OrderReadableEntity>();

如果需要批量注册程序集中的所有实现,可以通过扫描程序集自动注册:

// 获取包含实现类的程序集
var targetAssembly = typeof(CustomerReadableEntity).Assembly;

foreach (var implType in targetAssembly.GetTypes()
         .Where(t => !t.IsAbstract && !t.IsInterface
                     && t.GetInterfaces().Any(i => 
                         i.IsGenericType && 
                         i.GetGenericTypeDefinition() == typeof(IReadableEntity<>))))
{
    // 获取对应的IReadableEntity<T>接口类型
    var interfaceType = implType.GetInterfaces()
        .First(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IReadableEntity<>));
    
    // 注册到DI容器
    services.AddTransient(interfaceType, implType);
}

内容的提问来源于stack exchange,提问作者M. Ozn

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 17:20:17