微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

asp.net-mvc-4 – Quartz.NET触发器不会触发,MVC4

我在3层架构上有一个带有Unity依赖注入的MVC4 .Net Web应用程序,我希望每天都能提供一个版本并发送一些邮件.为此我想在Application_start中使用Quartz Scheduler,因为依赖注入windows服务不是一个好选择.

这是我在application_start中的代码.

// construct a scheduler factory
        ISchedulerFactory schedFact = new StdSchedulerFactory();
        IScheduler sched = schedFact.GetScheduler();
        sched.Start();

        IJobDetail dailyUserMailJob = new JobDetailImpl("DailyUserMailJob",null,typeof(SchedulerJob));
        // fire every time I open App/EveryDay
        ITrigger dailyUserMailTrigger = new SimpleTriggerImpl("DailyUserMailTrigger",1,new TimeSpan(1,0));
        sched.ScheduleJob(dailyUserMailJob,dailyUserMailTrigger);

这是我的工作代码

using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Web;
 using EvaluationMvc.Bll.Contracts;
 using Quartz;
 using Quartz.Impl;

namespace EvaluationMvc.Utils
{
   public class SchedulerJob : IJob
   { 
      private IEvaluationBus _iEvaluationBus;

      public SchedulerJob(IEvaluationBus iEvaluationBus)
      {
        //Dependency injection
          _iEvaluationBus = iEvaluationBus; 

      }
      public void Execute(IJobExecutionContext context)
      {
        _iEvaluationBus.testingArchitecture();
       // Sends a test mail.
      }
  }
}

但是我的工作从未执行过,可能是什么问题?

解决方法

必须将Quartz.net Scheduler创建为 singleton.

您可以安装Unity.MVC4 NuGet Package.
它将创建一个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实现.这article可能对你有帮助,this one值得一读:

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",typeof(Scheduler.SchedulerJob));
        // fire every time I open App/EveryDay
        ITrigger dailyUserMailTrigger = new SimpleTriggerImpl("DailyUserMailTrigger",10,new TimeSpan(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();

您可以在此link(QuartzWithUnity)之后找到工作示例.

原文地址:https://www.jb51.cc/aspnet/251975.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐