Pourquoi la mise en cache est un super-pouvoir pour chaque développeur C#
\nImaginez : votre application accède à chaque fois à la base de données pour la même liste de villes ou le même taux de change. La base de données est une ressource lente et coûteuse. Et si nous vous disions que vous pouvez répondre à l'utilisateur en 1 milliseconde au lieu de 100 ? Oui, ce n'est pas de la magie, mais une mise en cache des données en C# bien conçue.
\nLa mise en cache est une technique de stockage temporaire des données fréquemment demandées dans un stockage rapide (généralement en mémoire vive). Dans cet article, nous allons voir comment implémenter un cache dans les applications .NET, en utilisant à la fois des mécanismes intégrés et des solutions externes. Vous apprendrez à choisir la bonne stratégie et à éviter le piège des données obsolètes.
\n\nTypes de mise en cache en C# : de MemoryCache à Redis
\nDans l'écosystème .NET, il existe plusieurs approches pour la mise en cache. Le choix dépend de l'architecture de votre application : monolithe ou microservices, un seul serveur ou un cluster.
\n\n1. MemoryCache intégré (System.Runtime.Caching / Microsoft.Extensions.Caching.Memory)
\nLa méthode la plus simple et la plus rapide consiste à utiliser IMemoryCache. Les données sont stockées dans la mémoire vive du processus. Idéal pour les applications monothread ou les sites web simples.
Exemple d'enregistrement et d'utilisation dans ASP.NET Core :
\n// Dans Program.cs\nbuilder.Services.AddMemoryCache();\n\n// Dans un contrôleur ou un service\npublic class WeatherService\n{\n private readonly IMemoryCache _cache;\n\n public WeatherService(IMemoryCache cache)\n {\n _cache = cache;\n }\n\n public async Task<string> GetWeatherAsync(string city)\n {\n string cacheKey = $"weather_{city}";\n\n // Tentative de récupération des données depuis le cache\n if (_cache.TryGetValue(cacheKey, out string cachedData))\n {\n return cachedData;\n }\n\n // Si les données ne sont pas en cache, on les charge (ex : depuis une API)\n string weatherData = await FetchWeatherFromApi(city);\n\n // Sauvegarde dans le cache pour 10 minutes\n var cacheEntryOptions = new MemoryCacheEntryOptions()\n .SetAbsoluteExpiration(TimeSpan.FromMinutes(10));\n\n _cache.Set(cacheKey, weatherData, cacheEntryOptions);\n\n return weatherData;\n }\n}\nMéthodes clés : TryGetValue, Set, Remove. Notez les politiques d'expiration : durée absolue (les données expirent exactement après N minutes) et durée glissante (les données restent valides tant qu'elles sont consultées, et N minutes après la dernière requête).
2. Cache distribué : Redis via IDistributedCache
\nSi vous avez plusieurs instances d'application (ferme web, microservices), MemoryCache ne convient pas – chaque serveur stockera sa propre copie. Redis vient à la rescousse. Il fonctionne comme un serveur distinct, partagé par toutes les instances.
\nConnexion à Redis en C# :
\n// Installez le package : Microsoft.Extensions.Caching.StackExchangeRedis\nbuilder.Services.AddStackExchangeRedisCache(options =>\n{\n options.Configuration = "localhost:6379";\n options.InstanceName = "SampleInstance";\n});\n\n// Utilisation via IDistributedCache\npublic class ProductService\n{\n private readonly IDistributedCache _cache;\n\n public ProductService(IDistributedCache cache)\n {\n _cache = cache;\n }\n\n public async Task<Product> GetProductAsync(int id)\n {\n string cacheKey = $"product_{id}";\n var cachedProduct = await _cache.GetStringAsync(cacheKey);\n\n if (cachedProduct != null)\n {\n return JsonSerializer.Deserialize<Product>(cachedProduct);\n }\n\n var product = await FetchProductFromDb(id);\n var serialized = JsonSerializer.Serialize(product);\n\n await _cache.SetStringAsync(cacheKey, serialized, new DistributedCacheEntryOptions\n {\n AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(30)\n });\n\n