Libreria per la gestione della cache a doppio livello (L1: Memory + L2: Redis) basata su Microsoft.Extensions.Caching.Hybrid.
Per il corretto funzionamento della cache distribuita (Livello L2), è necessaria un'istanza di Redis attiva in ogni ambiente (Dev, Staging, Prod).
1. Configurazione ConnectionString
La libreria cerca la configurazione sotto la chiave ConnectionStrings:Redis. Assicurarsi che l'indirizzo e la password siano corretti:
{
"ConnectionStrings": {
"Redis": "indirizzo_host:porta,password=tua_password"
}
}2. Testing Locale con .NET Aspire/Docker
In fase di sviluppo locale, è consigliato l'uso di container Docker per avviare Redis.
Il progetto che integra questa libreria deve configurare la sezione CacheSettings e la stringa di connessione Redis nel file appsettings.json:
{
"CacheSettings": {
"Enabled": true,
"InstanceName": "Anagrafica_",
"Profiles": {
"Dipendente": {
"L1": 10,
"L2": 600,
"Mode": "DistributedOnly"
},
"Organizzazioni": {
"L1": 300,
"L2": 86400,
"Mode": "LocalOnly"
}
}
}
}Parametri dei Profili
- L1: Durata in secondi della cache in memoria locale (RAM).
- L2: Durata in secondi della cache distribuita (Redis).
- Mode
Both: Utilizza entrambi i livelli (Default).LocalOnly: Disabilita Redis, usa solo la RAM locale.DistributedOnly: Disabilita la RAM locale, forza la lettura da Redis.
1. Registrazione Servizi
Nel file Program.cs, registrare il servizio per configurare automaticamente Redis, HybridCache e il Wrapper:
using IntegrazioneCache.Extensions;
builder.Services.AddIntegrazioneCache(builder.Configuration);
2. Endpoint di Invalidazione Centralizzati
Per abilitare gli endpoint di pulizia della cache (nascosti da Swagger), aggiungere dopo il Build():
app.MapIntegrazioneCacheEndpoints();
1. Generazione Chiave (GenerateKey)
La libreria genera automaticamente chiavi univoche e deterministiche:
- Tipi Semplici: (int, long, string) ->
prefisso:valore. - Oggetti Complessi: Ispeziona le proprietà pubbliche ordinandole alfabeticamente per garantire la coerenza della chiave:
prefisso:Prop1_Val1:Prop2_Val2....
2. Esempio implementazione
Iniettare ICacheService per gestire lettura e scrittura:
public class MyRepository(ICacheService cache)
{
public async Task<Dato> GetData(long id)
{
string cacheKey = cache.GenerateKey("key", id);
return await cache.GetOrCreateAsync(
cacheKey,
async cancel => await FetchFromDb(id, cancel),
tags: ["my-tag"],
profileName: "Default"
);
}
}
Via Codice (Repository)
Usare i Tag per invalidare gruppi di dati correlati:
await _cache.RemoveByTagAsync($"dipendente-{id}");
Via HTTP (Endpoint Interni)
Gli endpoint sono protetti e non visibili su Swagger:
- Rimuovi per Tag:
DELETE /api/internal/cache/tag/{tag} - Rimuovi per Chiave:
DELETE /api/internal/cache/key/{key}
La libreria logga in console lo stato di ogni operazione per facilitare il debug:
[CACHE CALL]: Il wrapper è stato interpellato per una chiave specifica.[CACHE MISS]: Dato non trovato. Viene eseguita la factory (query al DB).[CACHE ERROR]: Errore Redis: Fallback automatico su DB/Factory eseguito.[CACHE BYPASS]: La cache è stata disabilitata globalmente da configurazione.
- Le date vengono formattate automaticamente come
yyyyMMddnelle chiavi. - Utilizzo di
ValueTaske binding tipizzato deirecordper ridurre l'utilizzo di memoria.