我想运行一个先前已在 ASP.NET Core 8 的 IoC 中注册的重复作业。
类似这样的:
基本上我对 Hangfire 有这个配置。
builder.Services.AddHangfire(config => config
.SetDataCompatibilityLevel(CompatibilityLevel.Version_180)
.UseSimpleAssemblyNameTypeSerializer()
.UseDefaultTypeSerializer()
.UseInMemoryStorage());
builder.Services.AddHangfireServer();
此后,我在 IoC 中注册了以下
MappingStoringGroup
类,如下所示:
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;
});
我正在寻找的是这样的:
app.UseHangfireDashboard();
RecurringJob.AddOrUpdate<ITaskGroup>("job id", nameof(MappingStoringGroup), tg => tg.RunTasks(), Cron.Hourly);
app.Run();
我必须在 IoC 中这样注册
MappingStoringGroup
有两个原因。首先,添加到 MappingStoringGroup
的所有任务类在构造函数中都有不同的依赖关系。其次,MappingStoringGroup.RunTasks()
也将通过控制器调用,手动执行任务。
我在注册
MappingStoringGroup
期间尝试使用Hangfire。
例如:
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();
RecurringJob.AddOrUpdate("job id", () => taskGroup.RunTasks(), Cron.Hourly);
return taskGroup;
});
但是没有成功。 Hangfire 仪表板将显示零重复作业。
正如线程中评论的那样,解决方案是创建一个自定义激活器:
public class HangfireCustomActivator(IServiceScopeFactory container) : JobActivator
{
public override object ActivateJob(Type type)
{
using var scope = container.CreateScope();
return scope.ServiceProvider.GetRequiredKeyedService<ITaskGroup>(type.Name);
}
}
然后在Hangfire配置中使用它。
builder.Services.AddHangfire((provider, config) => config
.SetDataCompatibilityLevel(CompatibilityLevel.Version_180)
.UseSimpleAssemblyNameTypeSerializer()
.UseDefaultTypeSerializer()
.UseInMemoryStorage()
.UseActivator(new HangfireCustomActivator(provider.GetRequiredService<IServiceScopeFactory>())));
builder.Services.AddHangfireServer();
这有效。但有点奇怪的是,Hangfire 没有在“Hangfire.AspNetCore”包中包含此功能。