2013-06-04 10 views
15

Sto cercando di ottenere Quartz.net (2.1.2) per funzionare con un contenitore IoC (autofac), poiché ho i servizi che devo usare nel programma lavori. Ho trovato post simili sull'argomento, ma non riesco a trovarne uno con un esempio di registrazione specifico per autofac.Come faccio a creare un lavoro di Quartz.NET che richiede l'iniezione con autofac

i seguenti offerte postali con lo stesso problema che sto avendo:

How to schedule task using Quartz.net 2.0?

Tuttavia, la parte credo che mi manca è quando la risposta dice: "E non dimenticate di registrare il lavoro in il contenitore IoC ". Non sono sicuro di come farlo esattamente, poiché tutto ciò che ho provato finora non ha funzionato.

Nell'esempio seguente, verrà eseguito "HelloJob", ma ogni volta che provo a iniettare releaseService nel "ReleaseJob", si rifiuta di eseguire.

Aggiornamento: Ho contrassegnato il codice nella sezione DependencyRegistration.cs in cui ritengo che il problema sia.

Aggiornamento 2: Alcuni link correlati che sono legati a quello che devo fare e potrebbe aiutare (ho già passato attraverso tutti loro, ma ancora non riesco a capire come ottenere questo lavoro con autofac):

COME USARE Quartz.NET in modo PRO? - http://blog.goyello.com/2009/09/21/how-to-use-quartz-net-in-pro-way/

Autofac e Quartz.NET - http://blog.humann.info/post/2013/01/30/Autofac-and-QuartzNET.aspx

Constructor iniezione con iniettori Quartz.NET e semplice - Constructor injection with Quartz.NET and Simple Injector

ASP.Net MVC 3, Ninject e Quarzo .Net - Come? - ASP.Net MVC 3, Ninject and Quartz.Net - How to?

Ecco il codice rilevante:

Global.asax

protected void Application_Start() 
    { 
     AreaRegistration.RegisterAllAreas(); 

     RegisterGlobalFilters(GlobalFilters.Filters); 
     RegisterRoutes(RouteTable.Routes); 

     var dependencyRegistration = new DependencyRegistration(); 
     dependencyRegistration.Register(); 

     ModelValidatorProviders.Providers.Clear(); 
     ModelValidatorProviders.Providers.Add(new FluentValidationModelValidatorProvider(new ValidatorFactory())); 

     DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false; 
    } 

DependencyRegistration.cs

public class DependencyRegistration 
{ 
    public void Register() 
    { 
     var builder = new ContainerBuilder(); 

     builder.RegisterControllers(Assembly.GetExecutingAssembly()); 
     builder.RegisterAssemblyModules(Assembly.GetExecutingAssembly()); 

     // Validation 
     builder.RegisterType<ValidatorFactory>() 
      .As<IValidatorFactory>() 
      .InstancePerHttpRequest(); 

     AssemblyScanner findValidatorsInAssembly = AssemblyScanner.FindValidatorsInAssembly(Assembly.GetExecutingAssembly()); 
     foreach (AssemblyScanner.AssemblyScanResult item in findValidatorsInAssembly) 
     { 
      builder.RegisterType(item.ValidatorType) 
       .As(item.InterfaceType) 
       .InstancePerHttpRequest(); 
     } 

     // Schedule 
     builder.Register(x => new StdSchedulerFactory().GetScheduler()).As<IScheduler>(); 

     // Schedule jobs 
     builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()).Where(x => typeof(IJob).IsAssignableFrom(x)); 

     var container = builder.Build(); 
     DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); 

     //Schedule 
     IScheduler sched = container.Resolve<IScheduler>(); 
     sched.JobFactory = new AutofacJobFactory(container); 
     sched.Start(); 

     IJobDetail job = JobBuilder.Create<ReleaseJob>() 
       .WithIdentity("1Job") 
       .Build(); 

     ITrigger trigger = TriggerBuilder.Create() 
      .WithIdentity("1JobTrigger") 
      .WithSimpleSchedule(x => x 
       .RepeatForever() 
       .WithIntervalInSeconds(5) 
      ) 
      .StartNow() 
      .Build(); 

     sched.ScheduleJob(job, trigger); 

     job = JobBuilder.Create<HelloJob>() 
       .WithIdentity("2Job") 
       .Build(); 

     trigger = TriggerBuilder.Create() 
      .WithIdentity("2JobTrigger") 
      .WithSimpleSchedule(x => x 
       .RepeatForever() 
       .WithIntervalInSeconds(5) 
      ) 
      .StartNow() 
      .Build(); 

     sched.ScheduleJob(job, trigger); 
    } 
} 

JobFactory.cs

public class AutofacJobFactory : IJobFactory 
{ 
    private readonly IContainer _container; 

    public AutofacJobFactory(IContainer container) 
    { 
     _container = container; 
    } 

    public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler) 
    { 
     return (IJob)_container.Resolve(bundle.JobDetail.JobType); 
    } 

    public void ReturnJob(IJob job) 
    { 
    } 
} 

ReleaseJob.cs

public class ReleaseJob : IJob 
{ 
    private readonly IReleaseService _releaseService; 

    public ReleaseJob(IReleaseService releaseService) 
    { 
     this._releaseService = releaseService; 
    } 

    public void Execute(IJobExecutionContext context) 
    { 
     Debug.WriteLine("Release running at " + DateTime.Now.ToString()); 
    } 
} 

public class HelloJob : IJob 
{ 
    public void Execute(IJobExecutionContext context) 
    { 
     Debug.WriteLine("Hello job at " + DateTime.Now.ToString()); 
    } 
} 

ReleaseServiceModel.cs

public class ReleaseServiceModule : Module 
{ 
    protected override void Load(ContainerBuilder builder) 
    { 
     builder.RegisterType<ReleaseService>() 
      .As<IReleaseService>() 
      .InstancePerLifetimeScope(); 
    } 
} 
+0

Mi hai salvato il tempo di capirlo. Grazie mille Tomas. – slashp

risposta

5

Ho finalmente rintracciato qual era il problema.

Il mio servizio di rilascio utilizzava un repository di dati che veniva creato con un ambito diverso.

Ho scoperto questo creando un nuovo servizio di test che non ha fatto altro che restituire una stringa e che ha funzionato per essere iniettato in un processo al quarzo.

Alla scoperta di questo, ho modificato l'ambito del repository richiamato dal servizio di rilascio, quindi il servizio di rilascio ha iniziato a funzionare all'interno del processo al quarzo.

Le mie scuse a chiunque abbia esaminato questa domanda per cercare di darmi una mano. Poiché il codice del servizio di rilascio non era elencato, sarebbe stato difficile capire cosa c'era di sbagliato.

Ho aggiornato il codice con gli attacchi di lavoro finali che ho usato per il quarzo con autofac.

+0

Ciao Thomas: mi dispiace di portare indietro un vecchio post, ma hai un esempio di come hai cambiato l'ambito del tuo servizio per tener conto di ciò. Sto cadendo nella stessa trappola dove non sono esperto nell'iniezione di dipendenza e non posso farlo funzionare:/ – SM3RKY

+0

Credo che stia cambiando l'ambito da "InstancePerHttpRequest" che non funzionava, a "InstancePerLifetimeScope" che ha funzionato, nel repository e moduli releaseervice. – Tomas

0

Il problema è che il vostro AutofacJobFactory non sta creando il ReleaseJob (si sta facendo questo con JobBuilder.Create<ReleaseJob>() invece), in modo che il contenitore CIO non è a conoscenza di esso è esemplificazione significa iniezione di dipendenza non può verificarsi.

Il seguente codice dovrebbe funzionare:

sched = schedFact.GetScheduler(); 
sched.JobFactory = new AutofacJobFactory(container); 
sched.Start(); 

// construct job info 
JobDetailImpl jobDetail = new JobDetailImpl("1Job", null, typeof(ReleaseJob)); 

ITrigger trigger = TriggerBuilder.Create() 
    .WithIdentity("1JobTrigger") 
    .WithSimpleSchedule(x => x 
     .RepeatForever() 
     .WithIntervalInSeconds(5) 
    ) 
    .StartNow() 
    .Build(); 

sched.ScheduleJob(jobDetail, trigger); 

Si noti che in questo esempio non stiamo usando più JobBuilder.Create<ReleaseJob>(), invece passiamo i dettagli del lavoro da creare tramite l'oggetto JobDetailImpl e facendo questo lo scheduler del jobfactory (il AutofacJobFactory) è responsabile per l'istanziazione del lavoro e può verificarsi l'iniezione di dipendenza.

+0

Ho apportato la modifica che hai consigliato. Ho rimosso JobBuilder.Create <> e l'ho sostituito con il tuo esempio. Tuttavia, il comportamento è sempre lo stesso. HelloJob funziona ma ReleaseJob no. – Tomas

+0

Suppongo che venga chiamato il metodo AutofacJobFactory.NewJob()? Se è così, è un problema con l'associazione. Come test è possibile modificare le righe di rilascio contrassegnate pertinenti a 'builder.RegisterType .As ();' e anche modificare la riga successiva in 'JobDetailImpl jobDetail = new JobDetailImpl (" 1Job ", null, typeof (IJob)); 'Si noti che questo testerà se i collegamenti verranno ora risolti, ma sarà necessario un factory astratto se si desidera istanziare più tipi di' IJob' – dcarson

+0

Ho inserito un breakpoint su AutofacJobFactory.NewJob(). Viene chiamato per HelloJob, ma non sembra mai attivarsi da ReleaseJob. Ho anche modificato il builder e i tipi di lavoro come indicato in IJob e li ho eseguiti solo uno alla volta. HelloJob ha funzionato di nuovo, ReleaseJob no. Grazie per tutto l'aiuto fino ad ora - non ho molta esperienza con gli attacchi e ho sospettato che fossero il problema qui da sempre, non sono sicuro di cosa provare per farli lavorare. – Tomas

Problemi correlati