Nello script #1061 abbiamo realizzato una classe helper che, sfruttando le lambda expression e i generics, ci consenta di semplificare il codice necessario all'uso della cache di ASP.NET.
Uno dei limiti di CacheHelper, però, è che non ci consente di fornire specifiche circa le policy con cui inserire in cache i vari oggetti. Una soluzione che si adatta alla maggior parte dei casi è quella di dotare il nostro helper di un dictionary statico, che potrà essere movimentato tramite il metodo RegisterPolicyFor<T> seguente:
public static class CacheHelper { private static Dictionary<Type, Func<CacheItemPolicy>> _policies = new Dictionary<Type, Func<CacheItemPolicy>>(); private static object _sync = new object(); public static void RegisterPolicyFor<T>(Func<CacheItemPolicy> policy) { lock(_sync) { _policies[typeof(T)] = policy; } } }
Il dictionary _policies associa ad ogni tipo un delegate, di tipo Func< CacheItemPolicy>, in grado di costruire opportunamente una CacheItemPolicy. La ragione per cui non memorizziamo direttamente un'istanza di CacheItemPolicy è che, tipicamente, specifichiamo un timeout basato sull'orario in cui l'elemento è stato inserito in cache, e quindi è opportuno che il CacheItemPolicy sia costruito nell'istante in cui verrà utilizzato. Come possiamo notare, inoltre, l'aggiunta di un nuovo elemento è eseguita all'interno di un blocco lock, dato che il dictionary non è thread safe.
La registrazione di una policy può avvire, pertanto, tramite una lambda expression, in questo modo:
CacheFactory.RegisterPolicyFor<List<Country>>( () => new CacheItemPolicy() { AbsoluteExpiration = DateTime.Now.AddHours(12) });
Il codice precedente, ad esempio, ha l'obiettivo di registrare una policy specifica per una lista di Country, tipicamente un dato estremamente statico, associando un timeout di 12 ore.
Questa policy verrà poi recuperata, all'interno di CacheHelper, integrando in questo modo il metodo GetItem<T> già visto nello script #1061:
public static T GetItem<T>(string key, Func<T> fetchDelegate) where T:class { // .. codice di check in cache e controllo if (result != null) { // aggiungiamo l'oggetto appena recuperato in cache, // con un timeout di 5 minuti cache.Add(key, result, GetPolicyFor<T>()); } return result; } private const int DEFAULT_TIMEOUT = 5; public static CacheItemPolicy GetPolicyFor<T>() { lock(_sync) { if (_policies.ContainsKey(typeof(T))) return _policies[typeof(T)](); return new CacheItemPolicy() { AbsoluteExpiration = DateTime.Now.AddMinutes(DEFAULT_TIMEOUT) }; } }
GetItem<T>, internamente, recuperare una policy tramite il metodo GetPolicyFor<T>: quest'ultimo verifica la presenza di una entry all'interno del dictionary _policies e, nel caso venga trovata, esegue il delegate corrispondente per creare la CacheItemPolicy; nel caso contrario, viene tornata una policy di default che, nel nostro esempio, imposta un timeout standard di 5 minuti.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Ottimizzare le pull con Artifact Cache di Azure Container Registry
Miglioramenti agli screen reader e al contrasto in Angular
Utilizzare un numero per gestire la concorrenza ottimistica con SQL Server ed Entity Framework
Utilizzare il metodo CountBy di LINQ per semplificare raggruppamenti e i conteggi
Gestire il colore CSS con HWB
Generare velocemente pagine CRUD in Blazor con QuickGrid
Creazione di plugin per Tailwind CSS: espandere le funzionalità del framework dinamicamente
Proteggere le risorse Azure con private link e private endpoints
Usare il colore CSS per migliorare lo stile della pagina
Selettore CSS :has() e i suoi casi d'uso avanzati
Eseguire query per recuperare il padre di un record che sfrutta il tipo HierarchyID in Entity Framework
Ordine e importanza per @layer in CSS