使用 Net8 进行 Quartz 依赖注入

问题描述 投票:0回答:1

我正在按照官方文档使用

.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;
    }
c# dependency-injection .net-8.0 quartz.net
1个回答
0
投票

好吧,你没有遵循官方文档。您不应该自己构建

StdSchedulerFactory
,它不知道您刚刚创建的 DI 配置,它是具有默认值的普通调度程序工厂。

您可能还想配置托管服务集成,它将自动处理调度程序的启动和停止。

© www.soinside.com 2019 - 2024. All rights reserved.