close up picture of cogs

Hangfire background tasks for .NET – Part 4: Hangfire Dashboard

We created jobs with the client and executed them on the server. Now it’s time to get some better insights using Hangfire Dashboard.

Web project setup

This time we’ll use the Hangfire Metapackage as it contains all the nice extension methods to easily host Hangfire Dashboard within our newly created empty ASP.NET Core application.

dotnet new web -n HangfireDashboard
dotnet sln add .\HangfireDashboard\
cd .\HangfireDashboard\
dotnet add package Hangfire
dotnet add package Microsoft.Data.SqlClient

Now we register Hangfire with the WebHost’s dependency injection container, configure the database connection and map the root path to the Hangfire Dashboard OWIN middleware. We do this directly in the web project’s Program.cs:

using Hangfire;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHangfire(config => 
    config.UseSqlServerStorage(@"
        Server=.;
        Database=MyApp;
        Integrated Security=True;
        TrustServerCertificate=True;
    ")
);
var app = builder.Build();

//map to root of application (/)
app.UseHangfireDashboard("");

app.Run();

That’s it. If we run the application and navigate to the URL displayed in the console (Now listening on: http://localhost:5000) Hangfire Dashboard comes up in all of its glory, displaying job information from our database.

A screenshot of Hangfire Dashboard's home page

Do I really need thee separate applications?

No, you don’t. In fact the Quickstart for ASP.NET Core even shows you how to make your Web application run the client, server and dashboard all at once. This is perfectly fine for small applications or internally used applications with limited traffic. I am not a big fan of running the hangfire server in the context of the web application. As you saw in Part 3, processing fails if the code Hangfire should execute does not exist on the Hangfire server. When you host everything in one app, the code will always be available until you need to scale out and add more Hangfire servers for processing. At this point you will realize that there is a lot of effort required to untangle the dependencies so you can actually add Hangfire servers without shipping your whole webapp alongside it. Separating the Hangfire server from the start will force you to think about dependency management and proper design before the need to scale out arises. Hosting the dashboard as part of the webapp that acts as a client is perfectly fine though.

What’s next?

First you should take a look at the available Extensions for Hangfire both from Hangfire’s creator and third party developers here. There is a lot of awesome stuff out there making Hangfire more powerful.

For this series the next thing is: show more “real-world” use cases. The jobs we created were minuscule and certainly far away from being useful. That’s ok because the focus was on Hangfire itself. Now we’ll create jobs that need to access some actual business logic including database access and logging. All this needs to work with our IoC/DI container of course. Often Hangfire is added to an existing web application to offload large pieces of work that previously was done within the context of an HTTP request where the controller had a logger, DAO, repository and other things conveniently injected by the DI container. We want to reuse that logic without rewriting everything.

Photo by Mark Hindle on Unsplash