2011-02-05 13 views
12

¿Alguien tiene alguna experiencia integrando autofac y Quartz.Net? De ser así, ¿dónde es mejor controlar la administración de por vida: IJobFactory, dentro de Execute of the IJob, o mediante escuchas de eventos?Autofac y Quartz.Net Integración


En este momento, estoy usando un autofac encargo IJobFactory para crear las IJob casos, pero no tienen una manera fácil de conectar a un ILifetimeScope en el IJobFactory para asegurar que cualquier costosos recursos que se inyectan en el IJob se limpian. La fábrica de trabajos solo crea una instancia de un trabajo y lo devuelve. Aquí están mis ideas actuales (esperemos que hay mejores ...)

  • Parece que la mayoría de las integraciones autofac alguna manera envuelven un ILifetimeScope alrededor de la unidad de trabajo que crean. La forma obvia de fuerza bruta parece ser pasar un ILifetimeScope en el IJob y hacer que el método Execute cree un hijo ILifetimeScope y crear una instancia de las dependencias allí. Esto parece un poco demasiado cercano al patrón de localización de servicios, que a su vez parece ir en contra del espíritu de autofac, pero podría ser la forma más obvia de garantizar el manejo adecuado de un alcance.

  • Pude conectarme a algunos de los eventos de Quartz para manejar las diferentes fases de la pila de ejecución de tareas y gestionar allí la gestión de la vida útil. Eso probablemente sería mucho más trabajo, pero posiblemente valga la pena si se logra una separación más clara de las preocupaciones.

  • asegurar que un IJob es un simple envoltorio alrededor de un tipo IServiceComponent, lo que hacer todo el trabajo, y solicitarlo lo Owned<T>, o Func<Owned<T>>. Me gusta cómo esto parece vibrar más con autofac, pero no me gusta que no sea estrictamente aplicable para todos los implementadores de IJob.

Respuesta

12

Sin saber demasiado sobre Quartz.Net y IJob s, voy a aventurar una sugerencia todavía.

Consideremos el siguiente envoltorio de empleo:

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

Teniendo en cuenta los siguientes registros:

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

Una fábrica de trabajo ahora podría resolver este envoltorio:

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

Nota: una lifetime scope creará como parte de la instancia ownedJob, que en este caso es del tipo Owned<SomeJob>. Cualquier dependencia requerida por SomeJob que es InstancePerLifetimeScope o InstancePerDependency se creará y destruirá junto con la instancia Owned.

+0

gracias por tomarse el tiempo para responder. Me gusta la idea porque es una versión más explícita de mi tercera lluvia de ideas en la pregunta original.Lo que todavía me molesta es que no tengo control sobre un alcance de por vida. Básicamente, me gustaría ejecutar cada IJob en su propio 'LifetimeScope', casi como el equivalente de una llamada de servicio WCF. La herramienta 'IJobFactory' de Quartz desafortunadamente es bastante disparada y se olvida de lo que he podido contar, por lo que puede ser que si realmente quiero límites explícitos de alcance, tendría que profundizar en el sistema de escucha de Quartz. –

+0

@dfaivre - He corregido un error en mi código, olvidé la parte 'ownedJob.Value'. Quizás mis intenciones sean más claras ahora. –

+3

No sabía que Owned creó un alcance; muy útil. Creo que este es probablemente el enfoque más directo, sin una inmersión profunda en la pila de Quartz. Probablemente aumentaré mi 'IJobFactory' para lanzar si el trabajo no es de tipo' JobWrapper <> '(solo para dormir un poco mejor por la noche ...). Gracias de nuevo por la gran visión. –