Featured image for .NET

The open source Infinispan data store is popular for in-memory operations. A .NET Core application can now easily integrate Infinispan as a caching service or session provider. This article provides basic information on how to do that in C# on Linux.

What you need:

  • .NET 6.0+ installed on your system
  • Access to get packages from NuGet
  • Access to an Infinispan server

On the Infinispan server, create a cache named default listening on the loopback host and port 127.0.0.1:11222, without authentication.

Create the application

You are going to work on an ASP.NET Core application, so run the following command to generate a new application scaffold:

dotnet new webapp -lang 'C#' -n Infinispan.Example.Caching -f net6.0

This command creates a new folder with an empty but working ASP.NET Core application. Run the application as follows:

cd Infinispan.Example.Caching
dotnet run

Check the application's log message for its HTTP or HTTPS URL and enter it into your browser to see the application's display.

Add Infinispan as a cache

The application requires the Infinispan caching package, so add it as follows:

dotnet add package Infinispan.Hotrod.Caching --version 0.0.1-alpha3

This package provides an IDistibutedCache implementation based on the Infinispan C# client, imported as a dependency.

Set up Infinispan as a cache provider

An ASP.NET Core application (6.0) provides all the services and pipeline setup in the Program.cs file. To this file, you need to add the Infinispan client configuration in the service setup, as well as session management in the process pipeline. Set the cache entries to expire after 10 seconds of idle time. Program.cs should now look like this:

using Infinispan.Hotrod.Core;
using Infinispan.Hotrod.Caching.Distributed;
var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
// Infinispan default setup is used:
// 127.0.0.1:11222 cacheName: default
builder.Services.AddInfinispanCache();
builder.Services.AddSession(options =>
{
    options.IdleTimeout = TimeSpan.FromSeconds(10);
    options.Cookie.HttpOnly = true;
    options.Cookie.IsEssential = true;
});

builder.Services.AddRazorPages();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();
app.UseSession();

app.MapRazorPages();

app.Run();

Add business code

Our business code is very simple: It presents some information (the user name, the age of the session, and the first access time) to the user as a result of a request. The data is fetched from the session cache if available there and computed by the program otherwise. This logic is implemented in the model file Pages/Index.cshtml.cs:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace Infinispan.Example.Caching.Pages
{

    public class IndexModel : PageModel
    {
        private readonly ILogger<IndexModel> _logger;

        public IndexModel(ILogger<IndexModel> logger)
        {
            _logger = logger;
        }

        public const string SessionKeyName = "_Name";
        public const string SessionKeyAge = "_Age";
        public const string SessionKeyFirstAccess = "_FirstAccess";
        public static Random RndSource = new Random();
        public string DataSource { get; private set; } = "";
        public void OnGet()
        {
            // Requires: using Microsoft.AspNetCore.Http;
            if (string.IsNullOrEmpty(HttpContext.Session.GetString(SessionKeyName)))
            {
                DataSource = "Computed";
                HttpContext.Session.SetString(SessionKeyName, "Mickey");
                HttpContext.Session.SetInt32(SessionKeyAge, RndSource.Next(100));
                HttpContext.Session.SetString(SessionKeyFirstAccess, DateTime.Now.ToString());
                return;
            }
            DataSource = "Cache";
        }
    }
}

The output is generated from a file named Pages/Index.cshtml:

@page
@using Infinispan.Example.Caching.Pages
@using Microsoft.AspNetCore.Http
@model IndexModel
@{
    ViewData["Title"] = "Home page";
}

<div class="text-center">
    <h1 class="display-4">Welcome</h1>
    <h2>The time on the server is @DateTime.Now</h2>

    <h2>Name (@Model.DataSource): @HttpContext.Session.GetString(IndexModel.SessionKeyName)</h2>
    <h2>Age (@Model.DataSource): @HttpContext.Session.GetInt32(IndexModel.SessionKeyAge)</h2>
    <h2>First Access Date (@Model.DataSource): @HttpContext.Session.GetString(IndexModel.SessionKeyFirstAccess)</h2>
    <p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>

Easy ASP.NET access to Infinispan

Everything is now in place for the show. Run your application again and check the output in the browser. The Age and the First Access Date field are computed the first time and cached for 10 seconds. The session itself expires after 10 seconds of idle time, as configured in the services configuration. Therefore, the cached values are reused by the application if requests come in quick succession.

This article has demonstrated how easily you can integrate Infinispan as a distributed cache and session provider for ASP.Net Core applications.

Explore more .NET tutorials on Red Hat Developer:

Last updated: August 14, 2023