2011-02-05 18 views
12

Qualcuno ha esperienza nell'integrazione di autofac e Quartz.Net? In tal caso, dov'è meglio controllare la gestione a vita: IJobFactory, all'interno di Execute of IJob o attraverso gli ascoltatori di eventi?Integrazione Autofac e Quartz.Net


In questo momento, sto usando un autofac personalizzato IJobFactory per creare le IJob casi, ma non hanno un modo semplice per collegare ad una ILifetimeScope nel IJobFactory per garantire tutte le risorse costose che vengono iniettati nel IJob vengono ripuliti. La fabbrica di lavoro crea solo un'istanza di un lavoro e la restituisce. Qui sono le mie idee correnti (si spera non ci sono di migliori ...)

  • Sembra che la maggior parte delle integrazioni autofac qualche modo avvolgono un ILifetimeScope intorno l'unità di lavoro che creano. Il modo ovvio di forza bruta sembra essere quello di passare uno ILifetimeScope nello e avere il metodo Execute creare un figlio ILifetimeScope e creare un'istanza di tutte le dipendenze presenti. Questo sembra un po 'troppo vicino a un modello di localizzatore di servizi, che a sua volta sembra andare contro lo spirito di autofac, ma potrebbe essere il modo più ovvio per garantire la corretta gestione di un ambito.

  • Ho potuto inserire alcuni degli eventi Quartz per gestire le diverse fasi dello stack di esecuzione del lavoro e gestire la gestione a vita. Probabilmente ci sarà molto più lavoro, ma forse ne valuterà la pena se diverrà più pulito la separazione delle preoccupazioni.

  • affinché un'IJob è un semplice involucro attorno a un tipo IServiceComponent, che tutto il lavoro, e chiedere come Owned<T>, o Func<Owned<T>>. Mi piace il modo in cui questo sembra avere più atmosfera con autofac, ma non mi piace che non sia strettamente applicabile per tutti gli implementatori di IJob.

risposta

12

Senza sapere troppo su Quartz.Net e IJob s, mi permetto un suggerimento ancora.

Si consideri il seguente involucro lavoro:

public class JobWrapper<T>: IJob where T:IJob 
{ 
    private Func<Owned<T>> _jobFactory; 

    public JobWrapper(Func<Owned<T>> jobFactory) 
    { 
     _jobFactory = jobFactory; 
    } 


    void IJob.Execute() 
    { 
     using (var ownedJob = _jobFactory()) 
     { 
      var theJob = ownedJob.Value; 
      theJob.Execute(); 
     } 
    } 
} 

Date le seguenti registrazioni:

builder.RegisterGeneric(typeof(JobWrapper<>)); 
builder.RegisterType<SomeJob>(); 

Una fabbrica di posti di lavoro potrebbe ora risolvere questo wrapper:

var job = _container.Resolve<JobWrapper<SomeJob>>(); 

Nota: un lifetime scope sarà cre come parte dell'istanza ownedJob, che in questo caso è di tipo Owned<SomeJob>. Qualsiasi dipendenza richiesta da SomeJob ovvero InstancePerLifetimeScope o InstancePerDependency verrà creata e distrutta insieme all'istanza Owned.

+0

grazie per aver dedicato del tempo per rispondere. Mi piace l'idea in quanto è una versione più esplicita del mio terzo brainstorming nella domanda originale.Quello che ancora mi infastidisce è che non ho il controllo su un ambito di vita. Fondamentalmente, mi piacerebbe eseguire ogni IJob nel proprio 'LifetimeScope', quasi come l'equivalente di una chiamata di servizio WCF. Il Quartz 'IJobFactory' sfortunatamente è abbastanza fuoco e dimentico di quello che sono stato in grado di dire, quindi potrebbe essere che se voglio davvero limiti di ambito espliciti, dovrei scavare nel sistema di ascolto Quartz. –

+0

@dfaivre - Ho corretto un bug nel mio codice, ho dimenticato la parte 'ownedJob.Value'. Forse le mie intenzioni sono più chiare ora. –

+3

Non sapevo che Owned abbia creato un ambito; molto utile. Penso che questo sia probabilmente l'approccio più diretto quindi senza un tuffo profondo nello stack di quarzo. Probabilmente aumenterò il mio 'IJobFactory' da lanciare se il lavoro non è di tipo' JobWrapper <> '(solo così dormo un po 'meglio di notte ...). Grazie ancora per la grande intuizione. –