C# Quartz.Net依赖项注入.Net核心

C# Quartz.Net依赖项注入.Net核心,c#,.net,asp.net-core,scheduler,quartz.net,C#,.net,Asp.net Core,Scheduler,Quartz.net,在我的项目中,我必须使用石英,但我不知道我做错了什么 工作工厂: 公共类IoCJobFactory:IJobFactory { 私有只读存储器ViceProvider工厂; 公共IoCJobFactory(IServiceProvider工厂) { _工厂=工厂; } 公共IJob NewJob(TriggerFiredBundle包,IScheduler调度器) { 作为IJob返回_factory.GetService(bundle.JobDetail.JobType); } 公共作业(IJ

在我的项目中,我必须使用石英,但我不知道我做错了什么

工作工厂:

公共类IoCJobFactory:IJobFactory
{
私有只读存储器ViceProvider工厂;
公共IoCJobFactory(IServiceProvider工厂)
{
_工厂=工厂;
}
公共IJob NewJob(TriggerFiredBundle包,IScheduler调度器)
{
作为IJob返回_factory.GetService(bundle.JobDetail.JobType);
}
公共作业(IJob作业)
{
var disposable=作业作为IDisposable;
if(一次性!=null)
{
一次性的,一次性的;
}
}
}
四次扩展:

公共静态类QuartzExtensions
{
公共静态void UseQuartz(此IApplicationBuilder应用程序)
{
app.ApplicationServices.GetService();
}
公共静态异步void AddQuartz(此IServiceCollection服务)
{
var props=新的NameValueCollection
{
{“quartz.serializer.type”,“json”}
};
变量工厂=新的StdSchedulerFactory(props);
var scheduler=wait factory.GetScheduler();
var jobFactory=new IoCJobFactory(services.BuildServiceProvider());
scheduler.JobFactory=作业工厂;
wait scheduler.Start();
AddSingleton(调度器);
}
}
当我尝试运行我的作业(类具有依赖项注入)时,我总是会遇到异常,因为:

始终为空

我的类实现了IJob,并在startup.cs中添加:

services.addScope();
services.AddQuartz();

我使用标准.net核心依赖项注入:


这就是我在我的应用程序中所做的。我没有将调度程序添加到ioc,而是只添加了工厂

services.AddTransient<IJobFactory, AspJobFactory>(
                (provider) =>
                {
                    return new AspJobFactory( provider );
                } );
services.AddTransient(
(提供商)=>
{
返回新工厂(供应商);
} );
我的工作工厂看起来几乎一样。暂时性并不重要,因为我只使用了一次。我使用的石英扩展方法是

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();
        }
publicstaticvoiduseQuartz(此IApplicationBuilder应用程序,动作配置)
{
//通过IOC容器的作业工厂
var jobFactory=(IJobFactory)app.ApplicationServices.GetService(typeof(IJobFactory));
//定岗工厂
Quartz.Instance.UseJobFactory(jobFactory);
//运行配置
configuration.Invoke(Quartz.Instance);
//天然石英
Quartz.Start();
}

Quartz
类也是单例。

这只是我解决IoC问题的简单示例:

JobFactory.cs

Startup.cs

QuartzStartup.cs

公共类QuartzStartup
{
private IsScheduler _scheduler;//启动后,直到关闭完成,都会引用scheduler对象
专用只读阅读器提供程序容器;
公共QuartzStartup(IServiceProvider容器)
{
this.container=容器;
}
//启动计划程序,定义作业和触发器
公开作废开始()
{
如果(_调度程序!=null)
{
抛出新的InvalidOperationException(“已启动”);
}
var schedulerFactory=new StdSchedulerFactory();
_scheduler=schedulerFactory.GetScheduler().Result;
_scheduler.JobFactory=新的JobFactory(容器);
_scheduler.Start().Wait();
var voteJob=JobBuilder.Create()
.Build();
var voteJobTrigger=TriggerBuilder.Create()
.StartNow()
.使用SimpleSchedule(s=>s
.间隔秒(60)
.RepeatForever())
.Build();
_ScheduleJob(voteJob,voteJobTrigger).Wait();
}
//启动计划程序的关闭,并等待作业正常退出(在分配的超时内)
公共停车场()
{
如果(_调度程序==null)
{
返回;
}
//给正在运行的作业30秒(例如)时间,使其正常停止
if(_scheduler.Shutdown(waitForJobsToComplete:true)。Wait(30000))
{
_调度程序=null;
}
其他的
{
//乔布斯没有及时退出-记录警告。。。
}
}
}  
考虑到您应该提前将您的服务注册到容器中(在我的例子中是VoteJob)。
我基于此实现此功能。
我希望它能有所帮助

我也有同样的问题

我从

services.addScope()

services.addScope()

然后它就起作用了


\u factory.GetService(bundle.JobDetail.JobType)作为IJob将不为空:)

Quartz.NET 3.1将包括对Microsoft DI和ASP.NET核心托管服务的官方支持

您可以通过以下方式找到重新访问的软件包:

  • -Microsoft DI集成
  • -ASP.NET核心集成
看到正在进行的新DI集成的最佳资源是前往


您是否在DI中安装了作业?是的,我只有一个作业,所以我通过
services.addScope()安装了它
Quartz.Instance
在我的示例
调度程序中
?和动作是什么?becouse
Quartz
在我的应用程序中“Quartz是一个名称空间,但像类型一样使用”
Quartz
是我定制的类。这是你非常有帮助的代码。你能在startup.cs中告诉我你不使用
services.AddQuartz()?而且
UseQuartz
需要配置,那么您如何将其添加到Startup.cs?这是我的Startup.cs@donex93中与石英相关的内容我不知道
using Microsoft.Extensions.DependencyInjection;
services.AddTransient<IJobFactory, AspJobFactory>(
                (provider) =>
                {
                    return new AspJobFactory( provider );
                } );
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();
        }
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();
        }
    }
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);
        }
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...
            }
        }
    }