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

Hangfire+Autofac报错ComponentNotRegisteredException:服务未注册

问题分析与解决

问题根源

你在ServiceCollection中完成了所有服务注册,直接通过serviceCollection.BuildServiceProvider()能正常获取DriverFileService并调用方法,但Hangfire执行任务时触发ComponentNotRegisteredException,核心原因是:

  • Hangfire配置了UseAutofacActivator(builder.Build()),但此处的Autofac容器未包含ServiceCollection中注册的任何服务(你没有将ServiceCollection的注册项导入到Autofac容器构建器中)。
  • Hangfire执行后台任务时,会使用配置的Autofac激活器来解析服务,而非你手动创建的serviceProvider,因此找不到已在ServiceCollection中注册的DriverFileService。

解决方案

1. 整合ServiceCollection与Autofac容器

将ServiceCollection中的所有服务注册导入到Autofac容器构建器中,确保Autofac容器包含完整的服务注册:

// 1. 保留你原有的ServiceCollection服务注册代码
var serviceCollection = new ServiceCollection()
    .AddScoped<BlobService>()
    .AddSingleton<IConfiguration>(configuration)
    .AddDbContext<RedactedDbContext>(opt => opt.UseNpgsql(connectionString))
    .AddScoped<ActivityChangeInfoCh>()
    .AddScoped<SpecificConditionsCh>()
    .AddScoped<CardIdentificationCh>()
    .AddScoped<UploadInfoCh>()
    .AddScoped<CardEventDataCh>()
    .AddScoped<CardFaultDataCh>()
    .AddScoped<CardVehiclesUsedCh>()
    .AddScoped<GNSSPlacesCh>()
    .AddScoped<HangfireService>()
    .AddTransient<FileReader>()
    .AddScoped<ExplorerService>()
    .AddScoped<DriverFileService>();

// 2. 创建Autofac容器构建器,导入ServiceCollection的注册
var builder = new ContainerBuilder();
builder.Populate(serviceCollection); // 关键步骤:将ServiceCollection服务导入Autofac

// 3. 构建完整的Autofac容器
var autofacContainer = builder.Build();

// 4. 配置Hangfire使用该Autofac容器作为激活器
GlobalConfiguration.Configuration
    .SetDataCompatibilityLevel(CompatibilityLevel.Version_180)
    .UseSimpleAssemblyNameTypeSerializer()
    .UseColouredConsoleLogProvider()
    .UseRecommendedSerializerSettings()
    .UsePostgreSqlStorage(config.GetConnectionString("Hangfire"))
    .UseAutofacActivator(autofacContainer);

2. 修正RecurringJob的定义

避免直接捕获外部的serviceProvider(Hangfire会序列化委托,ServiceProvider无法被正确序列化且执行时不会使用它),改用Hangfire支持的强类型解析方式:

using (var server = new BackgroundJobServer(options))
{
    Console.WriteLine("Hangfire Server started. Press any key to exit...");
    var manager = new RecurringJobManager();
    
    // 让Hangfire通过Autofac激活器自动解析DriverFileService
    manager.AddOrUpdate<DriverFileService>(
        "process2",
        service => service.Test(),
        "*/50 * * * * *"
    );

    Console.ReadKey();
}

3. 调整手动调用逻辑(可选)

如果需要保留手动调用TestAvailability()的逻辑,建议改用Autofac容器获取服务,保持容器一致性:

var driverFileService = autofacContainer.Resolve<DriverFileService>();
driverFileService.TestAvailability();

关键注意点

  • builder.Populate(serviceCollection)是核心,它会将ServiceCollection中所有AddScoped/AddSingleton/AddTransient的注册转换为Autofac对应的生命周期注册。
  • 不要在Hangfire任务委托中直接引用外部的ServiceProvider或容器实例,Hangfire的任务执行环境与主线程分离,必须依赖配置的激活器解析服务。

内容的提问来源于stack exchange,提问作者Stanley

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 09:45:16