Я создаю систему обмена сообщениями с запланированными заданиями для отправки смс-сообщений и электронных писем из очередей.Однако я не могу заставить приведенный ниже код работать с несколькими заданиями, он работает с одним заданием.У меня также возникает проблема, связанная с ошибкой задания: «Невозможно использовать область обслуживания !!! контекст !!! из синглтона !!! задание !!!».
Ниже приведена моя попытка реализации несколькихвакансии.
QuartzServicesUtilities
public static class QuartzServicesUtilities
{
public static void StartJob<TJob>(IScheduler scheduler, string cron)
where TJob : IJob
{
var jobName = typeof(TJob).FullName;
var job = JobBuilder.Create<TJob>()
.WithIdentity(jobName)
.Build();
var trigger = TriggerBuilder.Create()
.ForJob(job)
.WithCronSchedule(cron, x => x.WithMisfireHandlingInstructionIgnoreMisfires())
.WithIdentity($"{jobName}.trigger")
.StartNow()
.Build();
scheduler.ScheduleJob(job, trigger);
}
}
QuartzExtensions
public static class QuartzExtensions
{
public static void UseQuartz(this IServiceCollection services, params Type[] jobs)
{
services.AddSingleton<IJobFactory, JobFactory>();
services.Add(jobs.Select(jobType => new ServiceDescriptor(jobType, jobType, ServiceLifetime.Singleton)));
services.AddSingleton(provider =>
{
var schedulerFactory = new StdSchedulerFactory();
var scheduler = schedulerFactory.GetScheduler().Result;
scheduler.JobFactory = provider.GetService<IJobFactory>();
scheduler.Start();
return scheduler;
});
}
}
JobFactory
public class JobFactory : IJobFactory
{
private readonly IServiceProvider _serviceProvider;
public JobFactory(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
{
var jobDetail = bundle.JobDetail;
var job = (IJob)_serviceProvider.GetService(jobDetail.JobType);
return job;
}
public void ReturnJob(IJob job)
{
if (job is IDisposable disposable)
{
disposable.Dispose();
}
}
}
SMSJob
public class SMSJob : IJob
{
private readonly IMessagingRepository _messagingRepository;
private readonly ISMSEngine _smsEngine;
public SMSJob(IMessagingRepository messagingRepository, ISMSEngine smsEngine)
{
_smsEngine = smsEngine;
_messagingRepository = messagingRepository;
}
public async Task Execute(IJobExecutionContext context)
{
!!! the job !!!
await Task.CompletedTask;
}
}
EmailJob
public class EmailJob : IJob
{
private readonly IEmailEngine _emailEngine;
private readonly IMessagingRepository _messagingRepository;
public EmailJob(IMessagingRepository messagingRepository, IEmailEngine emailEngine)
{
_emailEngine = emailEngine;
_messagingRepository = messagingRepository;
}
public async Task Execute(IJobExecutionContext context)
{
!!! the other job !!!
await Task.CompletedTask;
}
}
Запуск
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void Configure(IApplicationBuilder app, IHostingEnvironment env, IOptions<AppSettings> settings)
{
app.UseDeveloperExceptionPage();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
var scheduler = app.ApplicationServices.GetService<IScheduler>();
QuartzServicesUtilities.StartJob<EmailJob>(scheduler, settings.Value.EmailCronSchedule);
QuartzServicesUtilities.StartJob<SMSJob>(scheduler, settings.Value.SMSCronSchedule);
}
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed
// for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));
#region Engines
!!! engines !!!
#endregion Engines
#region Providers
!!! providers !!!
#endregion Providers
#region Repositories
!!! repos !!! i.e.
services.AddTransient<IMessagingRepository, MessagingRepository>();
#endregion Repositories
services.AddDbContext<Context>();
services.UseQuartz(typeof(EmailJob));
services.UseQuartz(typeof(SMSJob));
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
}