#c# #asp.net-mvc #asp.net-core #dependency-injection #quartz
Вопрос:
Я попытался внедрить зависимость в свой Кварц. Мне нужно запустить планировщик с помощью моей программы после нажатия кнопки в моем веб-интерфейсе. В общем, у меня было:
this.job = JobBuilder.Create<Program>()
.WithIdentity("myJob", "group1")
.Build();
Но это выше просто запускает программу с конструктором по умолчанию (Program()).
К сожалению, у меня есть программа, которой нужен конструктор с параметрами:
public class Program : IJob, IProgram
{
private readonly IDataBaseService _databaseservice;
public Program(IDataBaseService databaseservice)
{
_databaseservice = databaseservice;
}
public async Task Execute(IJobExecutionContext context)
{
await _databaseservice.DoSmth();
}
Так что мне нужно позвонить Program(IDataBaseService databaseservice)
Я прочитал много руководств, руководств и примеров, но до сих пор не могу найти ответа. Большинство ответов касаются Quartz, начинающегося при запуске приложения, но я хочу, чтобы он начинался с инъекции depndency после того, как я использую кнопку в веб-интерфейсе.
Вот мой код:
Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<IDataBaseService, DB2Service>();
services.AddTransient<IJobFactory, MyJobFactory>();
services.AddSingleton<IMyScheduler, MyScheduler>();
services.AddSingleton<IProgram, Program>();
services.AddControllersWithViews();
}
Контроллер MVC SiteController.cs:
public class SiteController : Controller
{
private readonly IMyScheduler _MyScheduler;
private readonly IDataBaseService _DataBaseService;
private readonly IProgram _Program;
public SiteController(IMyScheduler MyScheduler, IDataBaseService DataBaseService, IProgram Program)
{
_MyScheduler = MyScheduler;
_DataBaseService = DataBaseService;
_Program = Program;
}
//this action is called after button click on web interface
public async Task<ActionResult> ButtonClick()
{
//This is where i want to start Quartz. I don't want it to start at start of app.
//I want it to start when I click button on web interface.
await MyScheduler.Run_A_Scheduler();
return OK();
}
}
MyJobFactory.cs:
public class MyJobFactory : IJobFactory
{
private readonly IServiceProvider _provider;
public MyJobFactory(IServiceProvider provider)
{
_provider = provider;
}
public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
{
try
{
return (IJob)this._provider.GetService(bundle.JobDetail.JobType);
}
catch (Exception e)
{
throw new SchedulerException(string.Format("Problem while instantiating job '{0}' from the ASPnet Core IOC", bundle.JobDetail.Key), e);
}
}
public void ReturnJob(IJob job)
{
var disposable = job as IDisposable;
disposable?.Dispose();
}
}
MyScheduler.cs:
public class MyScheduler: IMyScheduler
{
IScheduler scheduler;
IJobDetail job;
ITrigger trigger;
public MyScheduler(IJobFactory myJobFactory)
{
scheduler = new StdSchedulerFactory()
.GetScheduler()
.Resu<
scheduler.JobFactory = myJobFactory;
}
public async Task Run_A_Scheduler()//this is a function that I am calling from controler
{
this.job = CreateJob<Program>() //definition at the end
this.trigger = TriggerBuilder.Create()
.StartNow()
.WithSimpleSchedule(x => x
.WithIntervalInSeconds(20) //example with 20 seconds, normaly every other hour
.RepeatForever())
.Build();
await this.scheduler.ScheduleJob(job, this.trigger);
await this.scheduler.Start();
}
private IJobDetail CreateJob<T>() where T : IJob
{
return JobBuilder.Create<T>()
.WithIdentity(typeof(T).Name)
.Build();
}
}
Program.cs
public class Program : IJob, IProgram
{
private readonly IDataBaseService _databaseservice;
public Program(IDataBaseService databaseservice)
{
_databaseservice = databaseservice;
}
public async Task Execute(IJobExecutionContext context)
{
await _databaseservice.DoSmth();
}
Interfaces IDataBaseService, IMyScheduler, IProgram are mostly empty and just here for dependency injection sake.
IJobFactory is from Quartz library.
Please help. I tried many solutions, and still I don’t get it. I want to fire with Quartz schedule my Program.cs, which have constructor with parameters. I don’t know, how to invoke Program.cs with quartz schedule when I click button on web interface.