web-dev-qa-db-ja.com

Quartz.NETとSimple Injectorによるコンストラクターの注入

現在、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
    }
36
Thewads

このブログ投稿 によると、次のようにカスタムIJobFactoryを実装する必要があります。

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

    public SimpleInjectorJobFactory(
        Container container, params Assembly[] assemblies)
    {
        this.container = container;

        // By creating producers, jobs can be decorated.
        var transient = Lifestyle.Transient;
        this.jobProducers =
            container.GetTypesToRegister(typeof(IJob), assemblies).ToDictionary(
                type => type,
                type => transient.CreateProducer(typeof(IJob), type, container));
    }

    public IJob NewJob(TriggerFiredBundle bundle, IScheduler _)
    {
        var jobProducer = this.jobProducers[bundle.JobDetail.JobType];
        return new AsyncScopedJobDecorator(
            this.container, () => (IJob)jobProducer.GetInstance());
    }

    public void ReturnJob(IJob job)
    {
        // This will be handled automatically by Simple Injector
    }

    private sealed 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 async Task Execute(IJobExecutionContext context)
        {
            using (AsyncScopedLifestyle.BeginScope(this.container))
            {
                var job = this.decorateeFactory();
                await job.Execute(context);
            }
        }
    }
}

さらに、次の登録が必要です。

var container = new Container();

container.Options.ScopedLifestyle = new AsyncScopedLifestyle();

var factory = new StdSchedulerFactory();

IScheduler scheduler = await factory.GetScheduler();

scheduler.JobFactory = new SimpleInjectorJobFactory(
    container, 
    Assembly.GetExecutingAssembly()); // assemblies that contain jobs

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

container.Verify();
42
Steven

パーティーには遅れますが、 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();
2
howcheng