Intégration et Personnalisation du Cache Distribué Redis dans un Projet ABP vNext

Configuration de l'environnement Redis

Pour utiliser Redis comme backend de cache dans une application ABP vNext, assurez-vous d'abord qu'un serveur Redis est opérationnel. Pour un environnement de développement local, l'utilisation d'un conteneur Docker est une solution pratique.

Intégration des dépendances

L'intégration commence par l'ajout du package NuGet dédié au cache Redis dans votre projet. La référence au package Volo.Abp.Caching.StackExchangeRedis est essentielle.

<PackageReference Include="Volo.Abp.Caching.StackExchangeRedis" Version="3.0.5" />

Parammétrage de la connexion

Les paramètres de connexion au serveur Redis sont typiquement définis dans le fichier appsettings.json de l'application hôte.

{
  "Redis": {
    "IsEnabled": true,
    "Configuration": "localhost:6379,password=votreMotDePasse,defaultdatabase=0"
  }
}

Déclaration du module de cache

Dans la classe du module d'application principale (généralement le module de hosting), il faut déclarer une dépendance vers le module de cache Redis d'ABP.

[DependsOn(
    typeof(AbpCachingStackExchangeRedisModule) // Ajout de cette dépendance
    // ... autres modules dépendants
)]
public class MonApplicationHostingModule : AbpModule
{
    public override void ConfigureServices(ServiceConfigurationContext context)
    {
        // La configuration est automatiquement lue depuis appsettings.json.
        // La configuration programmatique est également possible ici.
    }
}

Outil de gestion des politiques de cache

Pour une gestion flexible des durées d'expiration, on peut créer une classe utilitaire qui encapsule la création des options de cache.

using Microsoft.Extensions.Caching.Distributed;

public static class CachePolicyHelper
{
    public static DistributedCacheEntryOptions CreateOptions(bool useAbsoluteExpiration, int durationSeconds = 60)
    {
        var safeDuration = durationSeconds > 0 ? durationSeconds : 60;
        var options = new DistributedCacheEntryOptions();

        if (useAbsoluteExpiration)
        {
            options.AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(safeDuration);
        }
        else
        {
            options.SlidingExpiration = TimeSpan.FromSeconds(safeDuration);
        }

        return options;
    }
}

Développement d'extensions de cache personnalisées

ABP expose une interface IDistributedCache. On peut étendre ses fonctionnalités avec des méthodes d'extension pour simplifier le modèle "Get or Create", où les données sont récupérées depuis le cache si elles existent, ou calculées et mises en cache sinon.

using System.Text.Json;
using Microsoft.Extensions.Caching.Distributed;

public static class DistributedCacheExtensions
{
    // Version asynchrone recommandée
    public static async Task<t> GetOrCreateAsync<T>(
        this IDistributedCache cache,
        string key,
        Func<Task<T>> factory,
        DistributedCacheEntryOptions? options = null)
    {
        var cachedData = await cache.GetStringAsync(key);
        if (cachedData != null)
        {
            return JsonSerializer.Deserialize<T>(cachedData)!;
        }

        T data = await factory();
        var serializedData = JsonSerializer.Serialize(data);
        await cache.SetStringAsync(key, serializedData, options);
        return data;
    }
}</t>

Utilisation dans les services applicatifs

L'itnerface IDistributedCache est injectée dans les services où la logique de mise en cache est nécessaire.

public class DonneesService : ApplicationService
{
    private readonly IDistributedCache _cache;

    public DonneesService(IDistributedCache cache)
    {
        _cache = cache;
    }

    public async Task<string> ObtenirStatistiquesAsync()
    {
        return await _cache.GetOrCreateAsync(
            "cles:statistiques",
            async () => await CalculerStatistiquesLourdesAsync(),
            CachePolicyHelper.CreateOptions(useAbsoluteExpiration: true, 300));
    }

    private Task<string> CalculerStatistiquesLourdesAsync()
    {
        // Simulation d'un calcul coûteux
        return Task.FromResult("données de statistiques calculées");
    }
}

Test dans un contrôleur

Les contrôleurs peuvent également interagir directement avec le cache, bien que cette logique soit mieux placée dans les services. Voici un exemple de test direct depuis un contrôleur.

[Route("api/test")]
public class TestCacheController : AbpController
{
    private readonly IDistributedCache _distributedCache;

    public TestCacheController(IDistributedCache distributedCache)
    {
        _distributedCache = distributedCache;
    }

    [HttpGet("rafraichir-cle")]
    public async Task<IActionResult> RafraichirDonnees(string cle, string valeur)
    {
        var politiques = CachePolicyHelper.CreateOptions(useAbsoluteExpiration: false, 120);
        await _distributedCache.SetStringAsync(cle, valeur, politiques);
        return Ok();
    }
}

Isolatino des données entre microservices

Lorsque plusieurs microservices partagent une même instance Redis, il est crucial d'isoler leurs données. La pratique courante consiste à attribuer une base de données Redis différente (par exemple defaultdatabase=1 vs defaultdatabase=2) à chaque service via leur configuration respective.

Étiquettes: abp-vnext Redis idistributed-cache distributed-caching stackexchange-redis

Publié le 26 juillet à 07h55