# ## 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没啥特别的,核心还是在于内部注入链的流向;