Por que o cache é o superpoder de todo desenvolvedor C#
\nImagine: sua aplicação acessa o banco de dados toda vez para obter a mesma lista de cidades ou taxa de câmbio. O banco de dados é um recurso lento e caro. E se disséssemos que você pode responder ao usuário em 1 milissegundo em vez de 100? Sim, isso não é mágica, mas sim um cache de dados em C# bem feito.
\nCache é a técnica de armazenamento temporário de dados frequentemente solicitados em um armazenamento rápido (geralmente na memória RAM). Neste artigo, vamos abordar como implementar cache em aplicações .NET, usando tanto mecanismos integrados quanto soluções externas. Você aprenderá como escolher a estratégia correta e não cair na armadilha de dados desatualizados.
\n\nTipos de cache em C#: do MemoryCache ao Redis
\nNo ecossistema .NET, existem várias abordagens para cache. A escolha depende da arquitetura da sua aplicação: monolítica ou microsserviços, um servidor ou cluster.
\n\n1. MemoryCache integrado (System.Runtime.Caching / Microsoft.Extensions.Caching.Memory)
\nA maneira mais simples e rápida é usar IMemoryCache. Os dados são armazenados na memória RAM do processo. Ideal para aplicações single-thread ou sites simples.
Exemplo de registro e uso no ASP.NET Core:
\n// Em Program.cs\nbuilder.Services.AddMemoryCache();\n\n// Em um controller ou 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 // Tenta obter dados do cache\n if (_cache.TryGetValue(cacheKey, out string cachedData))\n {\n return cachedData;\n }\n\n // Se não houver dados — carrega (por exemplo, de uma API)\n string weatherData = await FetchWeatherFromApi(city);\n\n // Salva no cache por 10 minutos\n var cacheEntryOptions = new MemoryCacheEntryOptions()\n .SetAbsoluteExpiration(TimeSpan.FromMinutes(10));\n\n _cache.Set(cacheKey, weatherData, cacheEntryOptions);\n\n return weatherData;\n }\n}\nMétodos principais: TryGetValue, Set, Remove. Observe as políticas de expiração: tempo absoluto (os dados expiram exatamente após N minutos) e tempo deslizante (os dados permanecem enquanto são acessados e por N minutos após a última requisição).
2. Cache distribuído: Redis via IDistributedCache
\nSe você tem várias instâncias da aplicação (web farm, microsserviços), o MemoryCache não é adequado — cada servidor armazenará sua própria cópia. O Redis vem para ajudar. Ele funciona como um servidor separado, compartilhado por todas as instâncias.
\nConexão com Redis em C#:
\n// Instale o pacote: Microsoft.Extensions.Caching.StackExchangeRedis\nbuilder.Services.AddStackExchangeRedisCache(options =>\n{\n options.Configuration = "localhost:6379";\n options.InstanceName = "SampleInstance";\n});\n\n// Uso 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