我正在按照官方文档使用
.NET 8
和 Quartz 3.11
,并且遇到了一个问题:我无法为实现 IJob 接口的作业正确配置依赖项注入。例如,MyExampleJob
有一个带有应该注入参数的构造函数,但它们没有。我使用空构造函数进行测试,它进入空构造函数,但不进入具有依赖项的构造函数。我已经配置了必要的依赖项,但它不起作用。我也尝试过使用 x.UseMicrosoftDependencyInjectionJobFactory()
,但此方法将被弃用。我读过几篇文章,但它们都是几年前发表的。
public static async Task<IServiceCollection> AddJobServices(this IServiceCollection services)
{
services.AddQuartz(q =>
{
q.UseMicrosoftDependencyInjectionJobFactory();
q.UseInMemoryStore();
q.UseDedicatedThreadPool(tp =>
{
tp.MaxConcurrency = 10;
});
q.AddJob<EventWithoutDrawReminderJob>(opts => opts
.WithIdentity(nameof(EventWithoutDrawReminderJob))
.StoreDurably()
.RequestRecovery());
});
services.AddQuartzHostedService(options =>
{
options.WaitForJobsToComplete = true;
options.AwaitApplicationStarted = true;
});
// Register jobs with DI
services.AddTransient<EventWithoutDrawReminderJob>();
var quartzProperties = new NameValueCollection
{
["quartz.serializer.type"] = "newtonsoft"
};
var factory = new StdSchedulerFactory(quartzProperties);
var list = await factory.GetAllSchedulers(); // Here it's a test an alternative but returns an empty list
var scheduler = await factory.GetScheduler();
scheduler.Start().Wait();
services.AddSingleton(scheduler);
return services;
}
工作定义:
public class EventWithoutDrawReminderJob : IJob
{
public IApplicationDbContext DbContext { get; set; }
public INotificationService NotificationService { get; set; }
public UserManager<ApplicationUser> UserManager { get; set; }
public RoleManager RoleManager { get; set; }
public ILogger Logger { get; set; }
// public EventWithoutDrawReminderJob()
// {
// Console.WriteLine(" > Starting JobExecution: EventWithoutDrawReminderJob"); // If I uncomment this line, the breakpoint stops here
// }
public EventWithoutDrawReminderJob(ApplicationDbContext dbContext,
INotificationService notificationService,
UserManager<ApplicationUser> userManager,
RoleManager roleManager,
ILogger logger)
{
// This code never runs
DbContext = dbContext;
NotificationService = notificationService;
UserManager = userManager;
RoleManager = roleManager;
Logger = logger;
}
public async Task Execute(IJobExecutionContext context)
{
// My code using the dependencies
}
}
在程序.cs中
...
builder.Services.AddApplicationServices(appSettings);
await builder.Services.AddJobServices();
...
AddApplicationServices 方法有:
public static IServiceCollection AddApplicationServices(this IServiceCollection services, IAppConfigurations appSettings)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(configuration.GetConnectionString("testDB"),
builder =>
{
builder.MigrationsAssembly(typeof(ApplicationDbContext).Assembly.FullName);
builder.EnableRetryOnFailure(3);
builder.CommandTimeout(30);
}
));
services.AddScoped<IApplicationDbContext>(provider => provider.GetRequiredService<ApplicationDbContext>());
// Configure Identity
services
.AddIdentityCore<ApplicationUser>(options =>
{
options.Password.RequiredLength = 6;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequireLowercase = false;
options.Password.RequireUppercase = false;
options.Password.RequireDigit = false;
})
.AddRoles<ApplicationRole>()
.AddTokenProvider<DataProtectorTokenProvider<ApplicationUser>>(TokenOptions.DefaultProvider)
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
services
.AddScoped<ApplicationUserManager>()
.AddScoped<RoleManager>();
services.AddScoped<INotificationService, NotificationService>();
return services;
}