我正在尝试将TopShelf与Quartz.net和Autofac一起使用.我下面的代码工作得很好.但是,这一行:
cfg.UsingQuartzJobFactory(() => container.Resolve<IJobFactory>());
似乎是错误的做事方式.有没有更好的方法告诉Topshelf使用自定义autofac jobfactory? jobfactory的生命范围是什么?我担心这行代码会在将来的某个时候引起一些麻烦.如何在不再需要时释放jobfactory?这条线是否正常?
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(); }); } }
解决方法
我认为你应该用容器初始化quartz Server,这个例子使用unity,但我确信可以使用其他容器.
try { var container = new UnityContainer(); schedulerFactory = CreateSchedulerFactory(); quartzscheduler = GetScheduler(); SyncPost.Initialize.RepositoryConfig(container); SyncPost.Initialize.AddToSchedulerContextCustomVars(quartzscheduler,container); quartzscheduler.JobFactory = new JobFactoryInjection(container); } catch (Exception e) { logger.Error("Server initialization Failed:" + e.Message,e); throw; }
JobFactoryInjection在哪里实现IJobFactory:
public class JobFactoryInjection : IJobFactory { private readonly UnityContainer container = new UnityContainer(); public JobFactoryInjection(UnityContainer container) { if (container == null) throw new ArgumentNullException("container","Container is null"); this.container = container; } public IJob NewJob(TriggerFiredBundle bundle,IScheduler scheduler) { // Return job registrated in container bundle.JobDetail.JobDataMap.Put(SyncUtils.ContextKeyCenterCode,scheduler.Context.Get(SyncUtils.ContextKeyCenterCode)); return (IJob)container.Resolve(bundle.JobDetail.JobType); } public void ReturnJob(IJob job) { } }
关于JobFactory的生命周期,不用担心.来自Quartz文档:“JobFactory只是激活作业类的新实例.您可能想要创建自己的JobFactory实现来完成诸如让应用程序的IoC或DI容器生成/初始化作业实例之类的事情”