Ответ 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
) в этом случае.