I have an Autofac container that I wish to add a lifetime Quartz.NET scheduler to using Autofac.Extras.Quartz. With the code as is below, a Quartz scheduler is instantiated with the set properties, but it seems the scheduler is killed off after the initialization step.
I first call Initialize
from my Program.cs
to create a new container for MyModule
.
MyModuleStartup.cs
private static IContainer? _container;
public static void Initialize()
{
var containerBuilder = new ContainerBuilder();
containerBuilder.RegisterModule(new QuartzModule());
_container = containerBuilder.Build();
MyCompositionRoot.SetContainer(_container);
QuartzStartup.Initialize(_container);
}
I register and configure QuartzAutofacFactoryModule
and QuartzAutofacJobsModule
as described in the package's documentation.
QuartzModule.cs
public class QuartzModule : Module
{
protected override void Load(ContainerBuilder builder)
{
var schedulerConfiguration = new NameValueCollection { { "quartz.scheduler.instanceName", "MyScheduler" } };
builder.RegisterModule(new QuartzAutofacFactoryModule
{
ConfigurationProvider = _ => schedulerConfiguration
});
builder.RegisterModule(new QuartzAutofacJobsModule(typeof(MyJob).Assembly));
}
}
I then initialize Quartz.NET.
QuartzModule.cs
internal static class QuartzStartup
{
private static IScheduler? _scheduler;
internal static void Initialize(IContainer container)
{
_scheduler = container.Resolve<IScheduler>();
_scheduler.Start().GetAwaiter().GetResult();
var myJob = JobBuilder.Create<MyJob>().Build();
var myTrigger = TriggerBuilder.Create().StartNow()
.WithSimpleSchedule(x => x.WithIntervalInSeconds(5).RepeatForever()).Build();
// I can confirm here that the instance name property of scheduler is MyScheduler
_scheduler.ScheduleJob(myJob, myTrigger).GetAwaiter().GetResult();
}
}
MyJob is a simple IJob
class with a single debug statement in its overridden Execute
method (with a debug on the line that is never hit).
MyJob.cs
public abstract class MyJob: IJob
{
public async Task Execute(IJobExecutionContext context)
{
// Based on debugging, this line is never hit.
Debug.WriteLine($"Job running at {DateTime.Now.ToString()}");
}
}
How can I properly instantiate a lifetime instance of Quartz.NET withing my container?
The QuartzAutofacJobsModule
doesn't register the class MyJob
because it is abstract
since abstract classes can't be instantiated. Remove that and everything works as expected.
public class MyJob: IJob
{
public async Task Execute(IJobExecutionContext context)
{
// Based on debugging, this line is never hit.
Debug.WriteLine($"Job running at {DateTime.Now.ToString()}");
await Task.CompletedTask;
}
}
Make sure your program doesn't exit before the first trigger fires. I've added a temporary delay at the end and made proper use of async
/await
just so the sample code you provided doesn't exit immediately.
internal static async Task Initialize(IContainer container)
{
_scheduler = container.Resolve<IScheduler>();
await _scheduler.Start();
var myJob = JobBuilder.Create<MyJob>().Build();
var myTrigger = TriggerBuilder.Create().StartNow()
.WithSimpleSchedule(x => x.WithIntervalInSeconds(5).RepeatForever()).Build();
// I can confirm here that the instance name property of scheduler is MyScheduler
await _scheduler.ScheduleJob(myJob, myTrigger);
await Task.Delay(10000);
}