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

