Quartz.net Scheduler 必须创建为singleton。
您可以安装Unity.MVC4 NuGet 包。
它将创建一个Bootstrapper类,该类应如下所示:
public static class Bootstrapper
{
public static IUnityContainer Initialise()
{
var container = BuildUnityContainer();
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
return container;
}
private static IUnityContainer BuildUnityContainer()
{
var container = new UnityContainer();
// Register your interfaces here.
RegisterTypes(container);
return container;
}
public static void RegisterTypes(IUnityContainer container)
{
}
}
然后你必须创建自己的JobFactory实现。这篇文章可能会对你有所帮助,这篇文章值得一读:
public class UnityJobFactory: IJobFactory
{
private readonly IUnityContainer container;
static UnityJobFactory()
{
}
public UnityJobFactory(IUnityContainer container)
{
this.container = container;
}
public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
{
var jobDetail = bundle.JobDetail;
var jobType = jobDetail.JobType;
try
{
return this.container.Resolve(jobType) as IJob;
}
catch (Exception ex)
{
throw new SchedulerException(string.Format(
CultureInfo.InvariantCulture,
"Cannot instantiate class '{0}'", new object[] { jobDetail.JobType.FullName }), ex);
}
}
public void ReturnJob(IJob job)
{
// Nothing here. Unity does not maintain a handle to container created instances.
}
}
以及您自己的StdSchedulerFactory实现:
public class UnitySchedulerFactory : StdSchedulerFactory
{
private readonly UnityJobFactory unityJobFactory;
public UnitySchedulerFactory(UnityJobFactory unityJobFactory)
{
this.unityJobFactory = unityJobFactory;
}
protected override IScheduler Instantiate(QuartzSchedulerResources rsrcs, QuartzScheduler qs)
{
qs.JobFactory = this.unityJobFactory;
return base.Instantiate(rsrcs, qs);
}
}
回到你的Unity Bootstrapper你必须注册你的接口:
private static IUnityContainer BuildUnityContainer()
{
var container = new UnityContainer();
container.RegisterType<ISchedulerFactory, UnitySchedulerFactory>(new ContainerControlledLifetimeManager());
container.RegisterType<IScheduler>(new InjectionFactory(c => c.Resolve<ISchedulerFactory>().GetScheduler()));
container.RegisterType<IQuartzScheduler, QuartzScheduler>(new ContainerControlledLifetimeManager());
container.RegisterType<IEvaluationBus, EvaluationBus>();
RegisterTypes(container);
return container;
}
我已经将我的服务调度程序封装在一个类中,以便我可以创建它单例:
public interface IQuartzScheduler
{
void Run();
void Stop();
}
和:
public class QuartzScheduler : IQuartzScheduler
{
private readonly ISchedulerFactory SchedulerFactory;
private readonly IScheduler Scheduler;
public QuartzScheduler(ISchedulerFactory schedulerFactory, IScheduler scheduler)
{
this.SchedulerFactory = schedulerFactory;
this.Scheduler = scheduler;
}
public void Run()
{
IJobDetail dailyUserMailJob = new JobDetailImpl("DailyUserMailJob", null, typeof(Scheduler.SchedulerJob));
// fire every time I open App/EveryDay
ITrigger dailyUserMailTrigger = new SimpleTriggerImpl("DailyUserMailTrigger", 10,
new TimeSpan(0, 0, 0, 20));
this.Scheduler.ScheduleJob(dailyUserMailJob, dailyUserMailTrigger);
this.Scheduler.Start();
}
public void Stop()
{
this.Scheduler.Shutdown(false);
}
}
正如您在本课程中所看到的,我将创建我的作业/触发器并启动调度程序。
现在在您的Application_Start (global.asax) 中,您可以“引导”您的 Unity 容器,获取服务调度程序并运行它。
var unityContainer = Infrastructure.Bootstrapper.Initialise();
unityContainer.Resolve<IQuartzScheduler>().Run();
您可以在此链接( QuartzWithUnity )之后找到一个工作示例。