I'm trying to use TopShelf together with Quartz.net and Autofac. The code I have below works just fine. However, this line:
cfg.UsingQuartzJobFactory(() => container.Resolve<IJobFactory>());
seems like the wrong way of doing things. Is there a better way of telling Topshelf to use the custom autofac jobfactory? What lifetime scope will the jobfactory have? I'm concerned this line of code is going to cause me some headaches sometime in the future. How do I release the jobfactory when it's no longer needed? Is this line okay as-is?
class Poller : IJob
{
private readonly ILogger _log;
public Poller(ILogger log)
{
_log = log;
_log.Info("Instantiating...");
}
public void Execute(IJobExecutionContext context)
{
_log.Info("Executing...");
}
}
class Program
{
static Autofac.IContainer BuildContainer()
{
var builder = new ContainerBuilder();
builder.RegisterModule<NLogModule>();
builder.RegisterModule<QuartzAutofacFactoryModule>();
builder.RegisterModule(new QuartzAutofacJobsModule(typeof(Poller).Assembly));
var container = builder.Build();
return container;
}
static void Main(string[] args)
{
var container = BuildContainer();
HostFactory.Run(cfg =>
{
cfg.UseNLog();
cfg.UseAutofacContainer(container);
cfg.SetDescription("DESCRIPTION");
cfg.SetDisplayName("DISPLAY");
cfg.SetServiceName("NAME");
cfg.UsingQuartzJobFactory(() => container.Resolve<IJobFactory>());
cfg.ScheduleQuartzJobAsService(q =>
{
q.WithJob(() => JobBuilder.Create<Poller>().Build());
q.AddTrigger(() => TriggerBuilder.Create().WithSimpleSchedule(b => b.WithIntervalInSeconds(20).RepeatForever()).Build());
});
cfg.StartAutomatically();
cfg.RunAsLocalSystem();
});
}
}
For reference: TopShelf.Quartz.ScheduleHobHostConfiguratorExtensions
Also reference: Autofac.Extras.Quartz.QuartzAutofacFactoryModule
I think you should initialize quartz Server with container, this example use unity, but I am sure that work with other containers.
where JobFactoryInjection implement IJobFactory:
About JobFactory lifetime, don't worry about it. From Quartz documentation: "JobFactory simply activates a new instance of the job class. You may want to create your own implementation of JobFactory to accomplish things such as having your application's IoC or DI container produce/initialize the job instance"