Hangfire is an open-source application that provides an easy way to perform background processing in your .NET (core) applications. Whether it's a one-time action, a recurring job, or a batch operation, Hangfire can handle it all. While Umbraco offers the ability to schedule recurring code using the BackgroundTaskRunner, you can't go wrong with Hangfire for better maintainability and statistics/graphs of your jobs! In this blog, we will be setting up Hangfire in a fresh installation of Umbraco 9, and write a recurring job with access to our Umbraco content! 🔥
Getting started with Umbraco 9
Just like in my Umbraco 9 & Docker tutorial, we'll be following the official Umbraco 9 beta installation guide available at Umbraco.com, but here's a short summary for you! (Credits to Bjarke Berg over at Umbraco)
To use the new beta release, we will need to insert a custom NuGet feed to our NuGet sources. This can be done by running the following command in a command prompt of your choosing:
'dotnet nuget add source "https://www.myget.org/F/umbracoprereleases/api/v3/index.json" -n "Umbraco Prereleases"'
Once this feed is available as a NuGet source, we can install the new Umbraco dotnet template:
'dotnet new -i Umbraco.Templates::9.0.0-beta001'
Now that the Umbraco template is available, you can create a new empty Umbraco project:
'dotnet new umbraco -n MyCustomUmbracoSolution'
We will be using the project name 'MyCustomUmbracoSolution' for the rest of this guide, but you can change it to whatever you like!
In CLI the project can be built by navigating to the newly created folder and running the build command:
'cd MyCustomUmbracoSolution'
'dotnet build'
At this point, the project is ready to be executed:
'dotnet run'
This will boot the project, and write the log to the console. The website is now running on the Kestrel server, it will be available on the ports written in the console.
Getting started with Hangfire
Hangfire Installation
To get started with Hangfire, we will be adding 3 new packages to our project, being Hangfire.AspNetCore, Hangfire.Core, and Hangfire.SqlServer. We can either install these packages using the terminal, using visual studio, or by adding the following lines into our .csproj file (which already includes our Umbraco.cms package).
Hangfire Database
After we have installed Hangfire into our project, we will need to create a new, in this case, MSSQL Database. Simply execute the following SQL command in SQL Server Management Studio or any other database connection tool to create an empty database.
'CREATE DATABASE [Hangfire] GO'
While we're here, if you don't already have a database available for Umbraco, let's create another empty database called 'Umbraco9'.
'CREATE DATABASE [Umbraco9] GO'
Before we configure the rest of our application, let's give Umbraco a start, so that we can configure the Umbraco connection first! Simply run your application as specified in the previous chapter, navigate to "/umbraco", and configure your connections to use our newly created Umbraco9 database!
Once we have our databases created, we can head over to our project's appsettings.json file, and add in our Hangfire connectionstring! We will call our connection 'hangfireConnection', and place it in the designated ConnectionStrings section! For demonstration purpose, I'll be using my localdb database with integrated security, which will make our ConnectionStrings section as follows:
Now let's configure Hangfire in our code!
Hangfire Configuration
Now that we have setup our database connections, we will need to configure a couple of features in our Startup.cs class. We will be going through the following steps:
- Configuring the Hangfire Client in our startup services
- Enabling the Hangfire Server in our startup services
- Enabling & mapping the '/hangfire' endpoint to our hangfire dashboard
- Creating a recurring job that accesses our Umbraco content!
Let's start with the first two steps! In our Startup.cs class, we'll scroll down until we find our "ConfigureServices(IServiceCollection services)" method. In here, we will extend our out-of-the-box configuration of Umbraco to also load the Hangfire Services (including our database connection).
Now we are set to start running background jobs, but first let's enable the Hangfire Dashboard! If we scroll down our startup file, we will need to add some code to our Configure method. In the following code snippet we specify that we want to enable the Hangfire Dashboard, enable Routing, en configure the endpoint where we want to be able to reach the Dashboard at (the default endpoint being '/hangfire')!
If you may have noticed, I also added two additional parameters to our method to be Dependency Injected by Hangfire, being IBackgroundJobClient & IRecurringJobManager. We will be using these parameters to configure our very first task!
Writing our recurring job
For our recurring job, we want to do something with Umbraco 9, to confirm we have access to all our Umbraco services from without our job. For demonstration purposes, we will be writing a simple class that uses the Umbraco IContentService and serilog Ilogger, that fetches one of our Content Nodes, and log it's Id using serilog! Why? For science! (and totally not because of my lack of inspiration... I'm sure you can think of better use-cases for this than me! Automatic publishing? Third Party API's? You name it!)
Let's start by creating the new class file for our very complex logic. We'll be naming it LogUmbracoContent.cs! In this class we will create a method called GetRootId, that will fetch our first available Root node from our dependency injected contentService, and log it's Id! You can copy and paste the following snippet if you wish to do so!
Pretty straight-forward right? right!
Remember the two additional parameters we added in the previous chapter, in the Configure method of our Startup.cs class? We can now use them to register our newly created class & method to Hangfire! For a one-time executing job, use the backgroundJobClient, for recurring tasks use the recurringJobManager. At the bottom of our Configure method, we will add the following line:
Here we specify that we want to Add or Update our newly created job, and that it should instantiate our class LogUmbracoContent.
- The first parameter we give this function will be the Id of our Job. In this case, simply "HelloWorld" will suffice!
- The second parameter will be the method we want to call when our job gets executed. In this case, we can access the methods of our LogUmbracoContent class before we specified it as our type.
- The third parameter will be our cron expression. If you're familiar with writing cron expressions, you can use any type here, for example the string '*/15 * * * *'Â being 'Run this method every 15 minutes'. If you're not experienced with cron expressions, you can use the static class Cron, which offers some helper methods like Minutely, Hourly, Daily, Weekly, etc.!
We are now set and ready to launch our application! Let's use our Dotnet Run command once again to run our application, and head over to our '/hangfire' URL!
In here, we can go the the "Recurring Jobs" tab, and we see that it has successfully registered our recurring job!
Attachment 1 - Recurring Jobs
To see more details of our newly created job, press the button under the "Last execution" column of our job! This will open the following page, showing you how many times the job has been executed, whether it failed or succeeded, how long it took to execute said method, and more!
Â
Attachment 2 - Job Details
Now we can head over to our logs/console, and see that we're outputting our Umbraco content Root Item's Id once every minute (if you created one in Umbraco)!
Â
🚀 Congratulations, you have successfully installed Hangfire & Umbraco 9! 🔥
Â
Conclusion
This article shows the process of creating a fresh install of Umbraco 9 based on the Umbraco 9 Beta template, installing and configuring Hangfire onto our Umbraco project, and creating our first Recurring Job that has access to the Umbraco ContentService! 🔥
If you have any further questions, feel free to contact me over at my socials available at the Contact page, and I'd love to hear about the amazing creations you're able to come up with, with this setup!
Sources used in this article:
Hangfire.io documentation: https://docs.hangfire.io/en/latest/index.html
Umbraco 9 Beta Release, https://umbraco.com/blog/umbraco-9-beta-release/