Quartz.Net Dependency Injection .Net Core

前端 未结 4 854
无人及你
无人及你 2021-01-11 15:08

In my project I have to use Quartz but I don\'t know what i do wrong.

JobFactory:

public class IoCJobFactory :         


        
相关标签:
4条回答
  • 2021-01-11 15:43

    This is how I did it in my application. Instead of adding the Scheduler to the ioc I only add the factory

    services.AddTransient<IJobFactory, AspJobFactory>(
                    (provider) =>
                    {
                        return new AspJobFactory( provider );
                    } );
    

    My job factory pretty much looks the same. Transient does not really matter as I only use this once anyway. My use Quartz extension method then is

    public static void UseQuartz(this IApplicationBuilder app, Action<Quartz> configuration)
            {
                // Job Factory through IOC container
                var jobFactory = (IJobFactory)app.ApplicationServices.GetService( typeof( IJobFactory ) );
                // Set job factory
                Quartz.Instance.UseJobFactory( jobFactory );
    
                // Run configuration
                configuration.Invoke( Quartz.Instance );
                // Run Quartz
                Quartz.Start();
            }
    

    The Quartz class is Singleton as well.

    0 讨论(0)
  • 2021-01-11 15:51

    I got the same issue.

    I update from

    services.AddScoped<IJob, HelloJob>();

    to

    services.AddScoped<HelloJob>();

    then it works.

    _factory.GetService(bundle.JobDetail.JobType) as IJob; will not be null :)

    0 讨论(0)
  • 2021-01-11 15:53

    Quartz.NET 3.1 will include official support for Microsoft DI and ASP.NET Core Hosted Services.

    You can find the revisited packages as:

    • Quartz.Extensions.DependencyInjection - Microsoft DI integration
    • Quartz.AspNetCore - ASP.NET Core integration

    The best resource the see the new DI integration in progress is to head to the example ASP.NET Core application.

    https://www.quartz-scheduler.net/2020/07/08/quartznet-3-1-beta-1-released/

    0 讨论(0)
  • 2021-01-11 15:56

    This is just a simple sample of my solution to solve IoC problem:

    JobFactory.cs

    public class JobFactory : IJobFactory
        {
            protected readonly IServiceProvider Container;
    
            public JobFactory(IServiceProvider container)
            {
                Container = container;
            }
    
            public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
            {
                return Container.GetService(bundle.JobDetail.JobType) as IJob;
            }
    
            public void ReturnJob(IJob job)
            {
                (job as IDisposable)?.Dispose();
            }
        }
    

    Startup.cs

    public void Configure(IApplicationBuilder app, 
                IHostingEnvironment env, 
                ILoggerFactory loggerFactory,
                IApplicationLifetime lifetime,
                IServiceProvider container)
            {
                loggerFactory.AddConsole(Configuration.GetSection("Logging"));
                loggerFactory.AddDebug();
    
                app.UseMvc();
    
                // the following 3 lines hook QuartzStartup into web host lifecycle
                var quartz = new QuartzStartup(container);
                lifetime.ApplicationStarted.Register(quartz.Start);
                lifetime.ApplicationStopping.Register(quartz.Stop);
            }
    

    QuartzStartup.cs

    public class QuartzStartup
        {
            private IScheduler _scheduler; // after Start, and until shutdown completes, references the scheduler object
            private readonly IServiceProvider container;
    
            public QuartzStartup(IServiceProvider container)
            {
                this.container = container;
            }
    
            // starts the scheduler, defines the jobs and the triggers
            public void Start()
            {
                if (_scheduler != null)
                {
                    throw new InvalidOperationException("Already started.");
                }
    
                var schedulerFactory = new StdSchedulerFactory();
                _scheduler = schedulerFactory.GetScheduler().Result;
                _scheduler.JobFactory = new JobFactory(container);
                _scheduler.Start().Wait();
    
                var voteJob = JobBuilder.Create<VoteJob>()
                    .Build();
    
                var voteJobTrigger = TriggerBuilder.Create()
                    .StartNow()
                    .WithSimpleSchedule(s => s
                        .WithIntervalInSeconds(60)
                        .RepeatForever())
                    .Build();
    
                _scheduler.ScheduleJob(voteJob, voteJobTrigger).Wait();
            }
    
            // initiates shutdown of the scheduler, and waits until jobs exit gracefully (within allotted timeout)
            public void Stop()
            {
                if (_scheduler == null)
                {
                    return;
                }
    
                // give running jobs 30 sec (for example) to stop gracefully
                if (_scheduler.Shutdown(waitForJobsToComplete: true).Wait(30000))
                {
                    _scheduler = null;
                }
                else
                {
                    // jobs didn't exit in timely fashion - log a warning...
                }
            }
        }  
    

    consider that you should register your service into the container (in my case VoteJob) in advance.
    I implement this based on this answer.
    I hope it can be helpful.

    0 讨论(0)
提交回复
热议问题