Missing ScheduleTasks in Xperience by Kentico? Simply integrate Hangfire

18/09/2024
Model.AuthorName
Milan Sustek

🛠️ A great stand-in for an essential tool.

The Kentico Schedule Task module has long been a core component of the Kentico platform, providing developers with the ability to automate processes, manage background tasks, and schedule recurring operations within their applications.

Xperience by Kentico may initially appear to lack this crucial module, which could be seen as a potential drawback. However, this challenge is easily addressed by the availability of popular open-source alternatives such as Hangfire.

In this guide, I'll walk you through the process of setting up Hangfire Recurring Jobs as a replacement for the Kentico Schedule Task module.
 

💡 Why did I choose Hangfire?

Hangfire is a popular open-source library designed for managing and executing background jobs in .NET applications. It provides a robust framework for creating, processing, and monitoring jobs, enabling developers to easily offload time-consuming tasks to the background.

One of Hangfire's standout features is its intuitive dashboard UI, which provides real-time insights into job statuses. This dashboard not only lets you monitor ongoing jobs but also gives you the ability to manually trigger jobs on demand, adding an extra layer of control and convenience to your application's background processing.

Prerequisities

Before we begin, ensure you have a working Xperience by Kentico web application, such as the Dancing Goat template.

Step 1: Install Hangfire Packages

We start with basic setup of Hangfire following instruction on Hangfire - Getting started.

First, you need to add the necessary NuGet packages to your project. Open your terminal and run the following commands:
dotnet add package Hangfire.Core
dotnet add package Hangfire.SqlServer
dotnet add package Hangfire.AspNetCore
These packages include everything you need to integrate Hangfire into your Xperience application.

Step 2: Configure Hangfire Services

Next, you’ll need to register necessary services. AddHangfire() sets up queueing services and AddHangfireServer sets up processing services.
builder.Services.AddHangfire(c =>
{
    // Configure SQL Server as a job storage.
    c.UseSqlServerStorage(
        // Obtain Kentico Database connection string.
        builder.Configuration.GetConnectionString(
            ConnectionHelper.ConnectionStringName));
});

// Add Hangfire Server which processes background jobs.
builder.Services.AddHangfireServer();

Step 3: Map the Hangfire Dashboard

For monitoring and managing background jobs, Hangfire provides a dashboard UI.

You can map Hangfire Dashboard UI simply by calling MapHangfireDashboard. Optionally setup custom authorization policy, or select XperienceAdministrationAccessPolicy. The XperienceAdministrationAccessPolicy is a built-in policy in Xperience by Kentico, ensuring that only authenticated users with administration access can view the dashboard.
// Map Hangfire Dashboard UI and setup required authorization
app.MapHangfireDashboard(new DashboardOptions
{
    Authorization = []
}).RequireAuthorization("XperienceAdministrationAccessPolicy");

You can optionally configure named CookieAuthenticationOptions to specify a custom redirection path for unauthorized requests. Without this configuration, users may be redirected to the default, non-existent path /Account/Login.
// Setup redirect path for unauthorized requests.
builder.Services.Configure<CookieAuthenticationOptions>(
    AdminIdentityConstants.APPLICATION_SCHEME,
    o =>
    {
        o.LoginPath = "/admin/logon";
    });

Step 4: Schedule reocurring Jobs

Now that everything is set up you can schedule background jobs, e.g. to schedule repeating task you just have to obtain IRecurringJobManager from dependency injection container and call its AddOrUpdate method. Here’s an example of how to schedule a job that runs every minute:
// Get IRecurringJobManager service from the application dependency injection container.
var manager = app.Services.GetRequiredService<IRecurringJobManager>();

// Configure desired schedule tasks.
manager.AddOrUpdate(
    "ScheduleTasks.TestJob",
    () => ScheduleTasks.TestJob(),
    Cron.Minutely());

Step 5: Handle Xperience Database Connections

When your background job interacts with the Xperience by Kentico database through Xperience API you have to call ContextUtils.ResetCurrent() to reset any ambient context which may prevent creation of a new database connection and could fail with exceptions as stated in documentation.
class ScheduleTasks
{
    public static async Task TestJob()
    {
        // Reset current thread context so each invocation gets the new one for proper handling of database connections.
        ContextUtils.ResetCurrent();

        // Example of a scheduled task logic - fetching user info from Kentico Xperience.
        await UserInfo.Provider.Get().GetEnumerableTypedResultAsync();

        // Additional logic for processing users or other tasks.
    }


Conclusion

By following these steps, you can easily integrate Hangfire into your Xperience by Kentico project, replacing the traditional Schedule Task module with an available open-source solution. 😊

You can find the full solution on Github: https://github.com/BiQ-Bluesoft/xperience-by-kentico-schedule-tasks