测试IServiceCollection服务解析时IOptions、ILogger报类型转换异常求解
异常产生原因
- 你遍历到的
IOptions<TOptions>、ILogger<TCategoryName>这类服务的注册条目,对应的ServiceType是开放泛型类型定义(未填充具体的泛型参数类型),.NET依赖注入容器不支持直接解析开放泛型类型定义,必须传入填充了具体类型参数的闭合泛型才能正常实例化。 - 你正常业务代码中使用的都是
IOptions<具体配置类>、ILogger<具体业务类>这类闭合泛型,所以可以正常解析,和测试代码的场景完全不同。 - 这类开放泛型的注册本质是容器的「泛型类型映射规则」,不是可直接解析的服务实例模板,只有传入具体泛型参数后,容器才会根据规则生成对应的闭合泛型实现。
解决方案
你需要在测试解析逻辑中过滤掉开放泛型类型的注册条目,仅测试闭合泛型和非泛型服务的解析即可,修改后的代码如下:
static void TestServiceResolve(IServiceCollection services) { var provider = services.BuildServiceProvider(); foreach (var item in services) { // 跳过开放泛型类型的注册条目 if (item.ServiceType.IsGenericTypeDefinition) { continue; } try { var serviceToResolve = item.ServiceType; var implementationService = provider.GetService(serviceToResolve); } catch (Exception ex) { // 可自行扩展记录解析失败的服务信息方便排查 Console.WriteLine($"服务 {item.ServiceType.FullName} 解析失败:{ex.Message}"); } } }
如果有特殊需求需要验证开放泛型的映射规则是否正确,可以自行构造测试用的闭合泛型类型进行解析验证,比如针对IOptions<>可以构造IOptions<TestConfig>类来测试规则是否生效。
内容的提问来源于stack exchange,提问作者Bruno
相关产品推荐
相关产品推荐

