受欢迎的博客标签

ASP.NET Core MVC Background Task-Using FluentScheduler

Published
I currently have a simple website setup with ASP.NET Core MVC (.NET 4.6.1), and I would like to periodically do some processes like automatically send emails at the end of every day to the registered members. After doing some searching, I came across two common solutions - Quartz.NET and FluentScheduler. Based on this SO thread, I found the approach of using FluentScheduler more easier to digest and use for my simple task. After quickly implementing the following lines of code into my Program.cs class, I had the emails going out successfully every minute (for testing purposes). 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(); } } However, now apart from sending emails I also need to do some back-end processing for e.g. updating the user records in the DB when mails are being sent out. For this, I normally inject my Entity Framework Context into the constructor of my controllers and use it to get/update SQL records. My question is, since I cannot really inject these services into the main method, where would be the appropriate place to initialize the registry and add jobs for scheduling? Thanks for the help, I am a little new to this so a little guidance would be much appreciated! You can define all your jobs and their schedules, by subclassing from FluentScheduler Registryclass. something like: 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 } } For injecting dependencies into jobs, you need to implement FluentScheduler IJobFactoryinterface. GetJobIntance method is called by FluentScheduler for creating job instances. Here you can use any DI library you want; In this sample implementation, I'm going to assume that you use 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>(); } } Now you can start your jobs in main method by calling: JobManager.JobFactory = new JobFactory(new StandardKernel(new MyNinjectModule())); JobManager.Initialize(new JobRegistry()); .