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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 12:27:16