C#中Autofac为何向构造函数注入null引发空引用异常?
C# 依赖注入场景下调用
_retryPolicyHelper.GetRetryPolicy<>()抛出空引用错误解决方案 空引用触发的核心前提是_retryPolicyHelper字段值为null,构造函数注入不会在所有场景下自动完成依赖实例化,按以下顺序排查即可解决问题:
首先修正代码本身的语法错误
你贴的代码存在3处明显语法问题,会直接导致字段赋值失效或编译失败:
- 字段修饰符书写错误:
read only是错误写法,C#中只读修饰符为连写的readonly,中间不能有空格 - 构造函数参数列表语法错误:参数列表末尾多余的分号会导致构造函数声明无效
- 方法内存在无效字符:
SomeName方法内的代码行前多打了两个反引号,属于无效语法
修正后的标准写法:
internal readonly IRetryPolicyHelper _retryPolicyHelper; internal readonly ILogger _logger; // 注意替换Constructor为你实际的类名,参数列表末尾不要加分号 public YourServiceClass(IRetryPolicyHelper retryPolicyHelper, ILogger logger) { _retryPolicyHelper = retryPolicyHelper; _logger = logger; } public async Task SomeMethod() { // 移除行首多余的反引号 var retryPolicy = _retryPolicyHelper.GetRetryPolicy<SomeReturnType>(); }
测试场景下的核心故障原因
构造函数自动注入依赖的前提是被测类的实例由DI容器构建和解析,单元测试默认不会自动加载DI容器,90%以上的同类错误都是测试代码初始化被测类时操作不当导致:
- 额外定义了无参构造函数,构造函数内没有给
_retryPolicyHelper字段赋值,测试时调用无参构造new实例 - 调用有参构造时给
retryPolicyHelper参数传了null
错误测试代码示例:
// 错误:第一个参数传null,会导致_retryPolicyHelper为null var testInstance = new YourServiceClass(null, Mock.Of<ILogger>()); await testInstance.SomeMethod(); // 执行到GetRetryPolicy时必然抛空引用
对应修复方案
根据你的测试类型选择对应处理方式:
- 单元测试场景:使用Mock框架(Moq、NSubstitute等)构建
IRetryPolicyHelper的模拟实例,不要传null,同时按需配置模拟方法的返回值
正确写法参考(Moq框架为例):
// 构建IRetryPolicyHelper的模拟实例 var mockRetryHelper = new Mock<IRetryPolicyHelper>(); // 配置GetRetryPolicy方法的返回值 mockRetryHelper.Setup(h => h.GetRetryPolicy<SomeReturnType>()) .Returns(Policy.Handle<Exception>().WaitAndRetryAsync(3, _ => TimeSpan.FromSeconds(1))); var mockLogger = Mock.Of<ILogger<YourServiceClass>>(); // 传入所有非空依赖初始化被测类 var testInstance = new YourServiceClass(mockRetryHelper.Object, mockLogger); // 执行测试逻辑不会触发空引用 await testInstance.SomeMethod();
- 集成测试场景:测试初始化时单独构建服务容器,将
IRetryPolicyHelper、日志组件、被测类都注册到服务集合中,再从服务容器解析被测类实例,不要直接new
参考写法:
var services = new ServiceCollection(); // 注册日志组件 services.AddLogging(builder => builder.AddConsole()); // 注册重试策略辅助类的实现 services.AddSingleton<IRetryPolicyHelper, RetryPolicyHelper>(); // 注册被测类 services.AddTransient<YourServiceClass>(); var serviceProvider = services.BuildServiceProvider(); // 从容器解析实例,会自动完成所有依赖注入 var testInstance = serviceProvider.GetRequiredService<YourServiceClass>();
额外排查点
如果是生产环境运行(非测试场景)触发该错误,检查DI注册代码,确认已经将IRetryPolicyHelper对应的实现类注册到了服务容器中,未注册的依赖会导致容器解析服务时无法传入正确实例。
内容的提问来源于stack exchange,提问作者Warfujjii
相关产品推荐
相关产品推荐

