使用FluentScheduler - ASP.NET核心MVC

ter*_*y96 7 asp.net-core-mvc fluentscheduler

我目前有一个简单的网站设置ASP.NET Core MVC(.NET 4.6.1),我想定期做一些过程,如每天结束时自动发送电子邮件给注册会员.

在做了一些搜索之后,我遇到了两个常见的解决方案 - Quartz.NET和FluentScheduler.

基于这个SO线程,我发现使用FluentScheduler的方法更容易消化并用于我的简单任务.在我的Program.cs类中快速实现以下代码行之后,我每分钟都成功发送电子邮件(用于测试目的).

public class Program
{
    public static void Main(string[] args)
    {
        var host = new WebHostBuilder()
            .UseKestrel()
            .UseContentRoot(Directory.GetCurrentDirectory())
            .UseIISIntegration()
            .UseStartup<Startup>()
            .Build();

            var registry = new Registry();
            JobManager.Initialize(registry);

            JobManager.AddJob(() => MyEmailService.SendEmail(), s => s
                  .ToRunEvery(1)
                  .Minutes());

            host.Run();

    }
}
Run Code Online (Sandbox Code Playgroud)

但是,现在除了发送电子邮件之外,我还需要进行一些后端处理,例如在发送邮件时更新数据库中的用户记录.为此,我通常将我的实体框架上下文注入到我的控制器的构造函数中,并使用它来获取/更新SQL记录.

我的问题是,因为我无法真正将这些服务注入main方法,哪里是初始化注册表和添加调度作业的适当位置?

感谢您的帮助,我对此有点新意,所以我会非常感谢您的指导!

小智 3

您可以通过从 FluentScheduler 类进行子类化来定义所有作业及其时间表Registry。就像是:

public class JobRegistry : Registry {

    public JobRegistry() {
        Schedule<EmailJob>().ToRunEvery(1).Days();
        Schedule<SomeOtherJob>().ToRunEvery(1).Seconds();
    }

}

public class EmailJob : IJob {

    public DbContext Context { get; } // we need this dependency, right?!

    public EmailJob(DbContext context) //constructor injection
    {
        Context = context;
    }

    public void Execute()
    {
        //Job implementation code: send emails to users and update database
    }
}
Run Code Online (Sandbox Code Playgroud)

为了将依赖项注入到作业中,您需要实现 FluentSchedulerIJobFactory接口。GetJobIntance方法由 FluentScheduler 调用来创建作业实例。在这里你可以使用任何你想要的DI库;在此示例实现中,我假设您使用 Ninject:

public class MyNinjectModule : NinjectModule {
    public override void Load()
    {
        Bind<DbContext>().To<MyDbContextImplemenation>();
    }
}

public class JobFactory : IJobFactory {

    private IKernel Kernel { get; }

    public JobFactory(IKernel kernel)
    {
        Kernel = kernel;
    }

    public IJob GetJobInstance<T>() where T : IJob
    {
        return Kernel.Get<T>();
    }
}
Run Code Online (Sandbox Code Playgroud)

现在您可以通过调用以下方式在 main 方法中开始您的工作:

JobManager.JobFactory = new JobFactory(new StandardKernel(new MyNinjectModule()));
JobManager.Initialize(new JobRegistry());
Run Code Online (Sandbox Code Playgroud)