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

ASP.NET Core 8中如何结合IoC使用Hangfire执行定时任务?

解决方案

问题根源

  • 你在服务注册工厂内添加RecurringJob的方式无效:Scoped服务的工厂方法仅在首次解析该服务时才会执行,若应用启动后未手动触发解析,这段代码根本不会运行,自然无法添加定时任务。
  • 你期望的RecurringJob.AddOrUpdate<ITaskGroup>写法有误:该重载无法识别带键服务,Hangfire不知道要解析哪个具体的ITaskGroup实现。

正确实现步骤

1. 保留现有服务注册

你的服务注册逻辑无需修改,继续使用:

builder.Services.AddKeyedScoped<ITask, MappingTask>(nameof(MappingTask));
builder.Services.AddKeyedScoped<ITask, StoringTask>(nameof(StoringTask));
builder.Services.AddScoped<IRepository, SqlRepository>();

builder.Services.AddKeyedScoped<ITaskGroup>(nameof(MappingStoringGroup), (provider, key) =>
{
    var taskGroup = new MappingStoringGroupBuilder()
                    .AddTask(provider.GetRequiredKeyedService<ITask>(nameof(MappingTask)))
                    .AddTask(provider.GetRequiredKeyedService<ITask>(nameof(StoringTask)))
                    .CreateTaskGroup();

    return taskGroup;
});

2. 在应用启动阶段添加定时任务

在app.Run()之前,通过应用的服务提供者手动解析带键的ITaskGroup,并配置Hangfire定时任务:

app.UseHangfireDashboard();

// 创建服务作用域,用于解析Scoped服务
using var scope = app.Services.CreateScope();
var serviceProvider = scope.ServiceProvider;

// 注册定时任务:委托中从容器解析带键的ITaskGroup并执行RunTasks
RecurringJob.AddOrUpdate("mapping-storing-job", 
    () => serviceProvider.GetRequiredKeyedService<ITaskGroup>(nameof(MappingStoringGroup)).RunTasks(), 
    Cron.Hourly);

app.Run();

3. (可选)自定义JobActivator优化带键服务解析

如果需要更优雅地处理带键服务的依赖注入,可以自定义Hangfire的JobActivator,让它支持带键服务的解析:

public class KeyedServiceJobActivator : JobActivator
{
    private readonly IServiceProvider _serviceProvider;

    public KeyedServiceJobActivator(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }

    public override object ActivateJob(Type type)
    {
        return _serviceProvider.GetService(type) ?? base.ActivateJob(type);
    }

    // 覆盖Resolve方法,支持带键构造参数的解析(按需扩展)
    public override object Resolve(Type type, JobActivatorContext context)
    {
        // 可根据自定义规则(如参数属性、命名约定)识别服务键,这里示例默认解析
        return _serviceProvider.GetService(type) ?? base.Resolve(type, context);
    }
}

然后在Hangfire注册时配置使用该Activator:

builder.Services.AddHangfire(config => config
                       .SetDataCompatibilityLevel(CompatibilityLevel.Version_180)
                       .UseSimpleAssemblyNameTypeSerializer()
                       .UseDefaultTypeSerializer()
                       .UseInMemoryStorage()
                       .UseActivator(new KeyedServiceJobActivator(builder.Services.BuildServiceProvider())));

效果验证

启动应用后,访问Hangfire仪表盘(默认路径/hangfire),即可看到名为mapping-storing-job的定时任务。任务执行时,Hangfire会自动从IoC容器解析所有依赖(包括MappingTask、StoringTask和SqlRepository)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 02:23:10