## # ## Quartz.net-IJobFactory实现任务实例创建的依赖注入  ## # ##
    在使用Quartz.net执行调度任务时,任务类必须实现IJob接口,如下
    `public class DLLExecutor : IJob
     {
        public async Task Execute(IJobExecutionContext context)
            {
                //你的处理逻辑
            
            }
     }`

    具备如上任务类之后,需要做的就是与JobDetial、Trigger进行关联,为了精简,忽略JobDetial、Trigger相关属性设置,代码如下

    `    //方式 1
        Type type = typeof(DLLExecutor);
        var jobBuilder = JobBuilder.Create(type);

        //方式 2
        var jobBuilder = JobBuilder.Create<DLLExecutor>();
    
        //创建ITrigger
        var triggerBuilder = TriggerBuilder.Create();
        
        //调度器
        var _scheduler = new StdSchedulerFactory().GetScheduler().GetAwaiter().GetResult();
    
        //绑定
        _scheduler.ScheduleJob(jobDetail, iTrigger);
        
    `
    
    好的,最简易的任务创建绑定完成,通过如上代码可知道,如果想在任务类中增加部分动态属性,只能**使用静态变量进行处理,且必须在使用前对静态变量进行赋值**,代码如下
    
    `public class DLLExecutor : IJob
     {
        //日志组件,默认Log4Net,但也允许是Log4net、Nlog、ExceptionLess等等
        public static ILogger Logger =log4net;

        public async Task Execute(IJobExecutionContext context)
            {
                //你的处理逻辑
                
            }
     }`
    所以如果你要使用非默认,你只能在绑定JobDetail之前进行赋值,代码如下
    
    `
        //先赋值再使用
        DLLExecutor.Logger = Exceptionless;

        //方式 1
        Type type = typeof(DLLExecutor);
        var jobBuilder = JobBuilder.Create(type);

        //方式 2
        var jobBuilder = JobBuilder.Create<DLLExecutor>();
    
        //创建ITrigger
        var triggerBuilder = TriggerBuilder.Create();
        
        //调度器
        var _scheduler = new StdSchedulerFactory().GetScheduler().GetAwaiter().GetResult();
    
        //绑定
        _scheduler.ScheduleJob(jobDetail, iTrigger);

    `
    
    从上述代码看,功能是完成,运行也是正常的,但问题来了,如果我用很多个类似于DLLExecutor的任务类,但可能需要特别处理的就不是日志组件了,该怎么办?
    1、在var jobBuilder = JobBuilder.Create(type)前一个一个的处理 ,
        请告诉我你不想(否则下面写不下去了)
    
    2、使用IJobFactory,实现依赖注入

    ### IJobFactory使用 ###
    
    首先改造任务类DLLExcecutor

    `public class DLLExecutor : IJob
     {
        
        //日志组件,默认Log4Net,但也允许是Log4net、Nlog、ExceptionLess等等
        
        //此时不需要是static,至于修饰符,个人习惯,可手动忽略

        protectd ILogger Logger =log4net;
        
        //因为使用的是.Net Core ,添加构造函数,用于注入
        //其他注入框架的话,自行选择合适的注入方式
        public DLLExecutor(ILogger logger)
        {
            Logger = logger;
        }
        
        public async Task Execute(IJobExecutionContext context)
            {
                //你的处理逻辑
                
            }
     }`
    
    完成任务类改造之后,在应用中进行注册,代码如下
    `
        //添加DLL执行者,生命周期自行决定
        services.AddSingleton<DLLExecutor>();
    
    `

    接着需要先创建个实现IJobFactory的工厂类,然后注册(是依赖注入还是自己new,随意,如果非注入方式,你就得思考怎么new了,本例全程使用注入方式)
    `
        public class DefaultScheduleServiceFactory : IJobFactory
        {
            /// <summary>
            /// 容器提供器,
            /// </summary>
            protected IServiceProvider _serviceProvider;
    
            /// <summary>
            /// 构造函数
            /// </summary>
            /// <param name="serviceProvider"></param>
            public DefaultScheduleServiceFactory(IServiceProvider serviceProvider)
            {
                _serviceProvider = serviceProvider;
            }
    
            /// <summary>
            /// 返回IJob
            /// </summary>
            /// <param name="bundle"></param>
            /// <param name="scheduler"></param>
            /// <returns></returns>
            public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
            {
                //Job类型
                Type jobType = bundle.JobDetail.JobType;
    
                //返回jobType对应类型的实例
                return _serviceProvider.GetService(jobType) as IJob;
            }
    
            /// <summary>
            /// 清理销毁IJob
            /// </summary>
            /// <param name="job"></param>
            public void ReturnJob(IJob job)
            {
                var disposable = job as IDisposable;
    
                disposable?.Dispose();
            }
        }
    `
    
    完成IJobFactory工厂类之后,需要做的就是与JobDetial、Trigger进行关联,对最原始的进行代码进行修改,代码如下

    `    //方式 1
        Type type = typeof(DLLExecutor);
        var jobBuilder = JobBuilder.Create(type);

        //方式 2
        var jobBuilder = JobBuilder.Create<DLLExecutor>();
    
        //创建ITrigger
        var triggerBuilder = TriggerBuilder.Create();
        
        //调度器
        var _scheduler = new StdSchedulerFactory().GetScheduler().GetAwaiter().GetResult();

        //使用IJobFactory,jobFactory为实现IJobFactory接口的实例
        _scheduler.IJobFactory = jobFactory;

        //绑定,
        //个人理解:猜测是在trigger触发时获取IJob,不知道是否正确,欢迎指正
        _scheduler.ScheduleJob(jobDetail, iTrigger);
        
    `

    到此,注入方式的实现全部已完成;个人觉得IJobFactory没啥特别的,核心还是在于内部注入链的流向;
    
    
    

posted on 2020-06-12 14:29  谭浈元  阅读(602)  评论(0)    收藏  举报