Подтвердить что ты не робот

Инъекция конструктора с Quartz.NET и простым инжектором

В настоящее время я пишу службу, использующую Quartz.NET, чтобы запланировать ее запуск.

Мне было интересно, есть ли у кого-нибудь опыт использования инъекции конструктора с Quartz.NET и Simple Injector.

Ниже, по сути, я хочу достичь

public class JobImplementation: IJob
{
    private readonly IInjectedClass injectedClass;

    public JobImplementation(IInjectedClass _injectedClass)
    {
         injectedClass = _injectedClass
    }

    public void Execute(IJobExecutionContext _context)
    {
        //Job code
    }
4b9b3361

Ответ 1

В соответствии с этот пост в блоге вам нужно будет выполнить пользовательский IJobFactory, например:

public class SimpleInjectorJobFactory : IJobFactory
{
    private readonly Dictionary<Type, InstanceProducer> jobProducers;

    public SimpleInjectorJobFactory(Container container, Assembly[] assemblies)
    {
        var types = container.GetTypesToRegister(typeof(IJob), assemblies);

        var lifestyle = Lifestyle.Transient;

        // By creating producers here by the IJob service type, jobs can be decorated.
        this.jobProducers = (
            from type in types
            let producer = lifestyle.CreateProducer(typeof(IJob), type, container) 
            select new { type, producer })
            .ToDictionary(t => t.type, t => t.producer);                
    }

    public IJob NewJob(TriggerFiredBundle bundle)
    {
        return (IJob)this.jobProducers[bundle.JobDetail.JobType].GetInstance();
    }
}

Кроме того, после сообщения в блоге вам понадобятся следующие регистрации:

var container = new Container();

container.Options.ScopedLifestyle = new AsyncScopedLifestyle();

var schedulerFactory = new StdSchedulerFactory();

container.RegisterSingle<IJobFactory>(
    new SimpleInjectorJobFactory(container, applicationAssemblies));
container.RegisterSingle<ILoadServiceScheduler, TimerScheduler>();
container.RegisterSingle<ISchedulerFactory>(schedulerFactory);
container.Register<IScheduler>(() => schedulerFactory.GetScheduler());

// Optional: register some decorators
container.RegisterDecorator(typeof(IJob), typeof(LoggingJobDecorator));

container.Verify();

Если у вас есть какие-либо регистрации в облачном стиле жизни, создание и выполнение заданий должно быть обернуто областью. Это можно сделать, например, с помощью декоратора:

public class AsyncScopedJobDecorator: IJob
{
    private readonly Container container;
    private readonly Func<IJob> decorateeFactory;

    public AsyncScopedJobDecorator(Container container, Func<IJob> decorateeFactory) {
         this.container = container;
         this.decorateeFactory = decorateeFactory;
    }

    public void Execute(IJobExecutionContext context) {
        using (AsyncScopedLifestyle.BeginScope(this.container)) {
            var job = this.decorateeFactory();
             job.Execute(context);
        }
    }
}

И зарегистрировать декоратор как последний декоратор следующим образом

container.RegisterDecorator<IJob, AsyncScopedJobDecorator>(Lifestyle.Singleton);

Это эффективно задерживает создание реальной работы до момента, когда выполняется декоратор. Это позволяет в этом случае использовать облачные сервисы (AsyncScopedLifestyle) в этом случае.

Ответ 2

Поздно к партии, но https://github.com/hbiarge/Quartz.Unity хорошо работает для объединения Quartz.NET и Unity.

IUnityContainer container = new UnityContainer();
container.AddNewExtension<Quartz.Unity.QuartzUnityExtension>();
// do your other Unity registrations
IScheduler scheduler = container.Resolve<IScheduler>();

scheduler.ScheduleJob(
    new JobDetailImpl(myCommandName, typeof(MyCommand)),
    TriggerBuilder.Create()
        .WithCronSchedule(myCronSchedule)
        .StartAt(startTime)
        .Build()
);
scheduler.Start();