C# Web API向ServiceCollection传递委托时解决空引用异常问题
问题根源
你遇到的空引用异常核心原因是:SummaryService.Delete是非静态方法,必须依赖类的有效实例才能调用,但你在Program.cs中创建委托时传入了null作为目标对象,且此时Scoped的SummaryService尚未被容器实例化,导致委托执行时找不到可用的类实例。
修改方案
1. 调整委托传递方式
不要直接传递已绑定实例的委托,改为传递一个能从服务容器中获取实例并执行方法的工厂委托,让类库在需要调用时自行从容器中获取有效实例。
修改调用方Program.cs代码:
builder.Services.AddServiceBusUserAccountDataDeletion("ServiceBusConsumerConfig", (sp, userId) => sp.GetRequiredService<SummaryService>().Delete(userId));
2. 更新类库扩展方法
修改扩展方法,接收工厂委托并注入服务容器:
public static IServiceCollection AddServiceBusUserAccountDataDeletion( this IServiceCollection services, string configSectionPath, Func<IServiceProvider, string, Task> deleteMethodFactory) { services.AddScoped<IDeletionService, DeletionService>(sp => new DeletionService(sp, deleteMethodFactory)); // 此处可补充ServiceBus消费者等相关注册逻辑 return services; }
3. 重构DeletionService
让服务持有服务容器引用,调用时创建独立作用域(适配后台进程的生命周期需求):
public class DeletionService : IDeletionService { private readonly IServiceProvider _serviceProvider; private readonly Func<IServiceProvider, string, Task> _deleteMethodFactory; public DeletionService(IServiceProvider serviceProvider, Func<IServiceProvider, string, Task> deleteMethodFactory) { _serviceProvider = serviceProvider; _deleteMethodFactory = deleteMethodFactory; } public async Task Delete(string userId) { // 后台进程调用Scoped服务时,必须创建独立作用域避免生命周期冲突 using var scope = _serviceProvider.CreateScope(); await _deleteMethodFactory(scope.ServiceProvider, userId).ConfigureAwait(false); } }
核心优势说明
- 无需调用方实现类库接口,完全通过委托解耦,符合你跨项目共享类库的需求。
- 利用服务容器的生命周期管理,确保
SummaryService实例始终有效,解决空引用问题。 - 后台进程中创建独立作用域,避免Scoped服务与单例服务(如ServiceBus消费者)的生命周期冲突。
内容的提问来源于stack exchange,提问作者user900566
相关产品推荐
相关产品推荐

