Currently I am writing a service using Quartz.NET to schedule the running of it.
I was wondering if anyone has any experience of using constructor injection with Qua
There are few steps to use Quartz.net with dependency injection engine from asp.net core.
Add nuget package to your project:
Microsoft.Extensions.DependencyInjection
Create custom JobFactory:
public class JobFactory : IJobFactory
{
protected readonly IServiceProvider _serviceProvider;
public JobFactory(IServiceProvider serviceProvider)
=> _serviceProvider = serviceProvider;
public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
=> _serviceProvider.GetService(bundle.JobDetail.JobType) as IJob;
public void ReturnJob(IJob job)
=> (job as IDisposable)?.Dispose();
}
Specify JobFactory when configuring scheduler:
var scheduler = await StdSchedulerFactory.GetDefaultScheduler();
scheduler.JobFactory = new JobFactory(_serviceProvider);
For someone can be usefull example of win service with Quartz.net and DI (from asp.net core) on the board:
public class WinService : ServiceBase
{
private Scheduler _scheduleManager;
private readonly Startup _startup;
public WinService()
{
ServiceName = "SomeWinService";
_startup = new Startup();
}
static void Main(string[] args)
{
var service = new WinService();
// Working as Windows-service
if (Console.IsInputRedirected && Console.IsOutputRedirected)
{
ServiceBase.Run(service);
}
// Working as console app
else
{
service.OnStart(args);
Console.WriteLine("Press any key to stop...");
Console.ReadKey();
service.OnStop();
}
}
protected override void OnStart(string[] args)
{
_startup.RegisterServices();
_scheduleManager = new Scheduler(_startup.ServiceProvider);
_scheduleManager.StartTracking().Wait();
}
protected override void OnPause()
=> _scheduleManager.PauseTracking().Wait();
protected override void OnContinue()
=> _scheduleManager.ResumeTracking().Wait();
protected override void OnStop()
{
_scheduleManager.StopTracking().Wait();
_startup.DisposeServices();
}
}
public class Startup
{
private IServiceProvider _serviceProvider;
public IServiceProvider ServiceProvider => _serviceProvider;
public void RegisterServices()
{
_serviceProvider = new ServiceCollection()
//.AddTransient(...)
//.AddScoped(...)
//.AddSingleton(...)
.BuildServiceProvider();
}
public void DisposeServices()
{
if (_serviceProvider == null)
return;
if (_serviceProvider is IDisposable)
{
((IDisposable)_serviceProvider).Dispose();
}
}
}
public class Scheduler
{
private readonly IServiceProvider _serviceProvider;
private IScheduler _scheduler;
public Scheduler(IServiceProvider serviceProvider)
=> _serviceProvider = serviceProvider;
public async Task StartTracking()
{
_scheduler = await StdSchedulerFactory.GetDefaultScheduler();
_scheduler.JobFactory = new JobFactory(_serviceProvider);
await _scheduler.Start();
// Schedule your jobs here
}
public async Task PauseTracking() => await _scheduler?.PauseAll();
public async Task ResumeTracking() => await _scheduler?.ResumeAll();
public async Task StopTracking() => await _scheduler?.Shutdown();
}