Faaaala galera! Faz um tempo que não escrevo algo, porém, comecei 2018 com planos de escrever frequentemente 😀
Decidi começar o ano falando sobre cache, inicialmente sobre o cache in-memory.
Introdução
O cache é uma maneira muito eficiente de aumentar consideravelmente a performance e escalabilidade de sua aplicação; ele evita processamento no servidor, como uma requisição no banco de dados, por exemplo. Assim sendo, as informações serão apresentadas de maneira mais rápida. É possível configurar o cache para que dure algum tempo, horas, dias, anos e por aí vai.
O cache funciona melhor com conteúdos que não são frequentemente alterados, pois ele faz uma “cópia” dos dados que serão retornados mais velozmente que do lugar original.
Cache no ASP .NET Core
O ASP .NET Core dá suporte a vários tipos de cache. O mais simples é baseado na interface IMemoryCache, onde o cache é salvo na memória do servidor web. Quando utilizamos vários servidores em escala é importante assegurar-nos de que o cache está indo para um único servidor.
O IMemoryCache irá remover o cache da memória de acordo com a alocação de memória para outros recursos, você pode ler mais aqui. Porém, se você definir a prioridade do cache para “nunca remover”, ele sempre continuará lá. Vou mostrar como fazer isso daqui a pouco!
Chega de teoria e bora colocar a mão na massa!
O cache in-memory é adicionado na classe Startup da sua aplicação via injeção de dependência como podemos ver a seguir:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public void ConfigureServices(IServiceCollection services) | |
{ | |
services.AddMemoryCache(); | |
services.AddMvc(); | |
} |
Em seguida, devemos utilizá-la no construtor da classe em que vamos brincar com o cache, a interface IMemeryCache vem do pacote Microsoft.Extensions.Caching.Memory do NuGet no caso desse exemplo, vou utilizar o meu Controller mesmo:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class HomeController : Controller | |
{ | |
private IMemoryCache _cache; | |
public HomeController(IMemoryCache memoryCache) | |
{ | |
_cache = memoryCache; | |
} | |
//resto do Controller… | |
} |
Vou fazer um exemplo com a data e hora atuais pra ficar bem didático, vejam o código a seguir, onde verificamos se existe a data no cache, e caso não exista, colocamos a data lá.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public IActionResult Index() | |
{ | |
//Verifica se existe ou não valor em um cache chamado "DataAtual" | |
if (!_cache.TryGetValue("DataAtual", out DateTime dataAtual)) | |
{ | |
//Caso não exista, colocamos a data atual | |
dataAtual = DateTime.Now; | |
//Aqui configuramos as opções do cache | |
var cacheEntryOptions = new MemoryCacheEntryOptions() | |
.SetAbsoluteExpiration(TimeSpan.FromSeconds(5)); //Tempo de expiração do cache | |
//Salvando 🙂 | |
_cache.Set("DataAtual", dataAtual, cacheEntryOptions); | |
} | |
ViewBag.DataAtual = dataAtual; | |
return View(); | |
} |
A minha View está da seguinte maneira:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@{ | |
ViewData["Title"] = "Home Page"; | |
} | |
<div class="row"> | |
<div class="col-md-12"> | |
<h2>Data atual</h2> | |
<p><b>@ViewBag.DataAtual</b></p> | |
</div> | |
</div> |
E o resultado por enquanto está assim:
O valor permanecerá no cache até o tempo limite, que em nosso caso é de 5 segundos.
Vejam este outro método onde vamos utilizar o método “GetOrCreate” para executar a mesma tarefa, aqui também vou colocar a prioridade para o cache nunca ser removido por alocação de memória.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public IActionResult GetOrCreateCache() | |
{ | |
var dataAtual = _cache.GetOrCreate("DataAtual", dataCache => | |
{ | |
dataCache.SetSlidingExpiration(TimeSpan.FromSeconds(10)); | |
dataCache.SetPriority(CacheItemPriority.NeverRemove); | |
return DateTime.Now; | |
}); | |
ViewBag.DataAtual = dataAtual; | |
return View(); | |
} |
E percebam, que a função só vai ser executada caso não exista valor no cache, do contrário, o que está entre as chaves não é executado.
Aqui vocês podem ver como está a View chamada por essa Action.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@{ | |
ViewData["Title"] = "Home Page"; | |
} | |
<div class="row"> | |
<div class="col-md-12"> | |
<h2>Data atual</h2> | |
<p>Data do cache: <b>@ViewBag.DataAtual</b></p> | |
<p>Data atual: <b>@DateTime.Now</b></p> | |
</div> | |
</div> |
E o resultado final:
O resultado é o mesmo, porém de uma maneira diferente e mais elegante de se escrever.
Ainda podemos remover um cache, utilizando o seguinte comando:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
_cache.Remove("DataAtual"); |
Fácil né?
Os exemplos de código estão disponíveis no GitHub: https://github.com/vmussak/NetCoreInMemoryCache/
Por hoje é só, qualquer dúvida ou sugestão, estou à disposição! Até mais 😀
Otimo artigo, conteúdo bem útil, de fácil entendimento, direto ao ponto sem enrolação. Parabéns
GostarGostar