Luke Warren Dev
Software Development Tips and Stories When I feel Like It

Scheduled Job Runner in an ASP.NET MVC App

simple apps do not need the feature bloat

,
Categories: ASP.NET , C#
Tags: C# , .NET , ASP.NET , Hangfire , Scheduled Jobs , DNN , MVC
Scheduled Job Runner in an ASP.NET MVC App

I have finally had the chance to build a few apps in vanilla ASP.NET MVC recently. While we still prefer DNN for many use cases, simple apps do not need the feature bloat you get when building on top of DNN. Sometimes in this vanilla context you find yourself missing things that you get for free in DNN.

Scheduled jobs

DNN provides an extremely easy and configurable way to run a task or "job" on a schedule. I needed something similar in an MVC app.

Turns out that it is not as hard as it seems when you break it down.

Find a job runner

First we needed something to actually handle running our recurring jobs. While you could write something yourself, that would be a waste of time considering it is a solved problem. I found a few nifty little libraries and decided that the best one to use would be Hangfire.

Hangfire allows you to easily run code on a schedule as well as monitor them via a dashboard (Hangfire has many many more features).

Discover our jobs

Now you could just use hangfire to run whatever code you want on a schedule off the bat but I wanted my implementation to require no code changes when a new job is needed to be run. You should just be able to write you code and have it run itself.

If I want to create a new job, it would just need to adhere to a contract that I defined. This simply meant creating a interface to act as my "contract"

My Interface:

```

public interface IScheduledJob {

string Frequency { get; }

void DoWork(); }

```

Now that I had a contract, I needed a way to discover all the classes that inherited  from my interface - ie all the "jobs" to register on app startup.

The following method is called in the Startup.Configure method and essentially just finds all the jobs and adds them to a recurring job schedule:

```

private void ConfigureSchedules(IAppBuilder app) { // Configure Dashboard GlobalConfiguration.Configuration.UseSqlServerStorage("DefaultConnection"); app.UseHangfireDashboard("/jobs", new DashboardOptions { AuthorizationFilters = new[] { new HangfireAuthorizationFilter() } }); app.UseHangfireServer();

// Get all types that implement the scheduler interface var jobs = AppDomain.CurrentDomain.GetAssemblies() .SelectMany(s => s.GetTypes()) .Where(p => typeof(IScheduledJob).IsAssignableFrom(p) && !p.IsInterface); foreach (var jobType in jobs) { // Create instance of job IScheduledJob job = (IScheduledJob)Activator.CreateInstance(jobType); // Add job to schedule RecurringJob.AddOrUpdate(() => job.DoWork(), job.Frequency); } }

```

*Note, for more information on the dashboard see the Hangfire docs *

Create a job

OK, now we are cooking on gas. We just need to create a class that inherits from our interface and it will automatically be added to the schedule

An example job:

```

public class TestSchedule : IScheduledJob
{
    public string Frequency
    {
        get
        {
            return Cron.Minutely();
        }
    }

    public void DoWork()
    {
        Debug.WriteLine($"Test Job Ran: {DateTime.Now}");
    }
}

```

Note that we use Hangfire's built in Cron class to define the frequency of our job. These methods simple return a string.

Happy scheduled-jobbing!


comments powered by Disqus