ASP.NET Core: dicas úteis para o dia a dia de um Desenvolvedor - Parte 6

Renato Groffe
6 min readSep 9, 2019

--

Neste novo post retomo a série de dicas úteis para o dia a dia de Desenvolvedores ASP.NET Core. Caso ainda não tenha consultado os 5 artigos anteriores ou, até mesmo, gostaria de revê-los acesse os links a seguir:

ASP.NET Core: dicas úteis para o dia a dia de um Desenvolvedor — Parte 1

ASP.NET Core: dicas úteis para o dia a dia de um Desenvolvedor — Parte 2

ASP.NET Core: dicas úteis para o dia a dia de um Desenvolvedor — Parte 3

ASP.NET Core: dicas úteis para o dia a dia de um Desenvolvedor — Parte 4

ASP.NET Core: dicas úteis para o dia a dia de um Desenvolvedor — Parte 5

E aproveito este espaço para deixar aqui ainda um convite.

Dia 17/09/2019 (terça) a partir das 21:30 — horário de Brasília — teremos mais uma live no Canal .NET. Desta vez eu (Renato Groffe) apresentarei diversas dicas e truques na utilização de containers Docker e englobando tecnologias como ASP.NET Core, .NET Core, Docker Compose, Kubernetes, SQL Server, MongoDB, Linux, MySQL, NGINX, Postgresql

Para efetuar a sua inscrição acesse a página do evento no Meetup. A transmissão acontecerá via YouTube, em um link a ser divulgado em breve.

RabbitMQ: evitando processamentos de longa duração em Web Apps

A prática de evitar processamentos de longa duração em aplicações Web pode ser facilmente implementada por meio de tecnologias de mensageria como o RabbitMQ. Soluções deste tipo se baseiam em um pattern conhecido como Fire-and-Forget, com o envio de mensagens para a manipulação posterior em um processo executando à parte de uma Web App.

Já abordei a utilização de RabbitMQ com ASP.NET Core no seguinte artigo (inclui repositório no GitHub):

.NET Core 2.2 + ASP.NET Core 2.2 + RabbitMQ: exemplos utilizando mensageria

O RabbitMQ também foi tema de uma live no Canal .NET neste ano de 2019:

O atributo ApiController: simplificando a codificação de APIs REST

Introduzido no ASP.NET Core 2.1, o atributo ApiController possibilita a implementação de APIs REST com um código mais enxuto e limpo. Isto acontece pelo fato de Controllers configurados com essa estrutura dispensarem:

  • O uso do atributo FromBody no parâmetro correspondente ao corpo de uma requisição;
  • Verificações no início de Actions a fim de determinar se os dados associados ao corpo da requisição são válidos, com isto acontecendo por meio da propriedade IsValid do objeto ModelState.

A utilização de ApiController já foi apresentada por mim no seguinte artigo:

ASP.NET Core 2.1: simplificando a codificação com o atributo ApiController

Na listagem a seguir temos um exemplo de Controller devidamente ajustado com o atributo ApiController:

Uma versão deste exemplo criada com o ASP.NET Core 2.2 pode ser encontrada no repositório:

ASP.NET Core 2.2 + ApiController

Dapper.Contrib: simplificando operações de CRUD com Dapper

Uma alternativa para facilitar a implementação de CRUDs com Dapper é o package Dapper.Contrib. Esta opção dispensa o uso de expressões SQL na implementação de instruções voltadas à manipulação de dados em tabelas com uma estrutura mais simplificada.

O Dapper.Contrib permite a utilização dos seguintes métodos com um objeto de conexão:

T Get<T>(id);
IEnumerable<T> GetAll<T>();
int Insert<T>(T obj);
int Insert<T>(Enumerable<T> list);
bool Update<T>(T obj);
bool Update<T>(Enumerable<T> list);
bool Delete<T>(T obj);
bool Delete<T>(Enumerable<T> list);
bool DeleteAll<T>();

A classe que representa um registro/entidade em uma tabela deverá passar por ajustes:

  • Os diversos atributos de configuração esperados pelo Dapper.Contrib se encontram no namespace Dapper.Contrib.Extensions;
  • O atributo Table associado à declaração da classe indica a tabela à qual a mesma se refere;
  • Já o atributo Key vinculado a uma propriedade indica que o valor representado pela mesma é gerado automaticamente (no caso do SQL Server, campos configurados como IDENTITY representam chaves auto-incremento).

Para campos nos quais o valor da chave primária deve ser informado manualmente será utilizado o atributo ExplicitKey, como indicado na próxima listagem (um exemplo envolvendo um tipo chamado Estado):

Ainda considerando a classe Comentario, na listagem a seguir temos a implementação de ComentariosController (tipo que permitirá a consulta e a inclusão de dados representados por Comentario):

  • O método GetAll<T> do Dapper.Contrib retornará todos os registros existentes em GetComentarios;
  • Get<T> permitirá a consulta a um comentário específico por meio de seu ID na Action Get;
  • O método Insert<T> possibilitará o cadastramento de um novo comentário na Action Post;
  • Nota-se em ComentariosController a ausência de qualquer instrução SQL graças ao uso do Dapper.Contrib.

Disponibilizei no GitHub 2 exemplos de utilização do Dapper.Contrib:

ASP.NET Core 2.2 + ApiController + Dapper.Contrib + FluentValidation + SQL Server

ASP.NET Core 2.2 + Dapper.Contrib + SQL Server

FluentValidation: maior flexibilidade em validações

E retomando o exemplo da API de comentários abordado na seção sobre Dapper.Contrib, detalharei agora o uso de FluentValidation como alternativa para simplificar e trazer maior flexibilidade à escrita de regras de validação em aplicações ASP.NET Core. Para isto será empregado o package FluentValidation.AspNetCore.

A classe ComentarioValidator conterá as diversas regras esperadas para os dados a serem inseridos através da API REST:

  • Este tipo herda de AbstractValidator<T> (namespace FluentValidation), referenciando ainda a classe Comentario;
  • No construtor de ComentarioValidator chamadas ao método RuleFor permitirão via expressão lambda selecionar os campos que passarão por verificação, bem como as regras de validação para os mesmos;
  • No exemplo aqui abordado foram especificadas regras através dos métodos NotEmpty (preenchimento obrigatório, desconsiderando strings contendo apenas espaços ou nulas), MinimumLength (tamanho mínimo em número de caracteres) e MaximumLength (tamanho máximo em número de caracteres);
  • Outros exemplos de métodos usados na montagem de regras de validação são NotNull (valores não nulos), GreaterThan (maior que) e LessThan (menor que).

Ajustes também ocorrerão na classe Startup:

  • O método AddFluentValidation será acionado em ConfigureServices (linha 25);
  • O tipo ComentarioValidator foi adicionado por meio de uma chamada a AddTransient, a fim de que referências envolvendo o mesmo sejam preenchidas via mecanismo de injeção do ASP.NET Core (linha 27).

A classe permanecerá idêntica ao exemplo da seção anterior e sem qualquer menção ao uso de FluentValidation, uma vez que o uso do atributo ApiController também é compatível com esta biblioteca:

A seguir temos um exemplo envolvendo o preenchimento incorreto de dados (testes via Postman), bem como a apresentação de mensagens de alerta definidas por meio de FluentValidation:

Esse exemplo também está no GitHub:

ASP.NET Core 2.2 + ApiController + Dapper.Contrib + FluentValidation + SQL Server

Polly: aplicações resilientes e um melhor tratamento de falhas

Uma ocorrência bastante comum, sobretudo em aplicações legadas, é a presença de inúmeros blocos try-catch encadeados ou não e geralmente relacionados a um mesmo fluxo de processamento. Muito embora esta prática atenda a muitas necessidades relacionadas ao tratamento de erros, há uma forte tendência em se chegar a um código extenso e difícil manutenção conforme o projeto cresce.

E que tal implementarmos mecanismos de recuperação de falhas de maneira elegante, empregando para isto padrões como Retry, Fallback, Timeout e Circuit Breaker e obtendo assim aplicações mais resilientes? É o que a biblioteca Polly se propõe a fazer dentro da plataforma .NET, possuindo total compatibilidade com .NET Standard (o que viabiliza seu uso em .NET Core/ASP.NET Core, Xamarin, ASP.NET clássico, .NET Full).

Recentemente detalhei o uso de Polly implementando o pattern Retry no artigo (inclui repositório no GitHub):

.NET Core + Polly + JWT: tratando de forma resiliente a expiração de tokens

Se você chegou até aqui e tem interesse em conhecer mais sobre o desenvolvimento de soluções Web utilizando o Azure, aproveito este espaco para mais um convite… Que tal aprender mais sobre a nuvem Microsoft, em um workshop que acontecerá durante um sábado (dia 21/09) em São Paulo Capital e implementando na prática um case que combina o uso de tecnologias como Azure App Service, Azure SQL, Azure Storage, Azure Functions e Application Insights? Acesse então o link a seguir para efetuar sua inscrição com um desconto especial: http://bit.ly/anp-dicas-aspnet

E concluo este artigo deixando o link de uma live recente do Canal .NET, em que abordamos através de exemplos práticos o uso de alguns dos frameworks/tecnologias aqui mencionados, além de diversas outras soluções - MediatR, Polly, ASP.NET Core Identity, HTTP REPL, Entity Framework Core, Dapper Contrib, AspNetCore.Diagnostics.HealthChecks, xUnit, Fluent Assertions, FluentValidation e AutoMapper:

--

--

Renato Groffe
Renato Groffe

Written by Renato Groffe

Microsoft Most Valuable Professional (MVP), Multi-Plataform Technical Audience Contributor (MTAC), Software Engineer, Technical Writer and Speaker