2014-11-19 23 views
7

Sto provando a utilizzare TopShelf insieme a Quartz.net e Autofac. Il codice che ho qui sotto funziona perfettamente. Tuttavia, questa riga:Topshelf deve utilizzare la fabbrica di lavoro al quarzo di Autofac

cfg.UsingQuartzJobFactory(() => container.Resolve<IJobFactory>()); 

sembra il modo sbagliato di fare le cose. C'è un modo migliore per dire a Topshelf di usare il custom autofac? Quale ambito di vita avrà il posto di lavoro? Sono preoccupato che questa linea di codice mi causerà dei mal di testa in futuro. Come posso rilasciare la workstation quando non è più necessaria? Questa linea va bene così com'è?

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(); 

     }); 
    } 
} 

Per riferimento: TopShelf.Quartz.ScheduleHobHostConfiguratorExtensions

Riferimento: Autofac.Extras.Quartz.QuartzAutofacFactoryModule

risposta

0

penso che si dovrebbe inizializzare quarzo Server con contenitore, questo esempio utilizzare l'unità, ma sono sicuro che il lavoro con altri contenitori.

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; 
     } 

dove JobFactoryInjection implementare 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) { 

    } 
} 

A proposito di vita JobFactory, non ti preoccupare. Dalla documentazione di Quartz: "JobFactory attiva semplicemente una nuova istanza della classe di lavoro. Potresti voler creare la tua implementazione di JobFactory per realizzare cose come avere l'IoC o il contenitore DI dell'applicazione produrre/inizializzare l'istanza di lavoro"