.NET Core + Serverless: melhorando a experiência de Desenvolvimento com Azure Functions 3.x | pt 2

Renato Groffe
Azure na Pratica
Published in
7 min readJul 6, 2020

Recentemente participei de 2 lives no Canal .NET com meu amigo Milton Câmara e que focaram na implementação de soluções serverless com .NET Core + Azure Functions 3.x. Nosso objetivo com estes eventos foi demonstrar que é possível aproximar a experiência de desenvolvimento com Azure Functions daquilo a que muitos Desenvolvedores estão habituados em ASP.NET Core. Para isto abordamos:

  • Mensageria com Azure Queue Storage, Azure Service Bus (filas e tópicos), RabbitMQ e Apache Kafka;
  • O uso de injeção de dependências com Azure Functions + .NET Core;
  • Utilização do Redis como solução de armazenamento de dados;
  • Acesso a dados com Dapper, Dapper.Contrib e soluções de ORM como Entity Framework Core e FluentNHibernate;
  • Validações com FluentValidation;
  • O uso de HttpClientFactory e da biblioteca Refit;
  • Resiliência com a biblioteca Polly;
  • Chaos Engineering utilizando de forma combinada Polly + Simmy.

Este é o segundo post da série de 3 artigos que estou produzindo sobre o uso de Azure Functions com as tecnologias apresentadas nos eventos online mencionados. Além das gravações de cada uma das lives, trago aqui também dicas/orientações sobre acesso a dados com diferentes soluções e como implementar validações sem grandes complicações em Function Apps.

Deixo aqui também o link com o primeiro artigo da série, caso ainda não tenha acessado o mesmo ou até deseje revê-lo:

.NET Core + Serverless: melhorando a experiência de Desenvolvimento com Azure Functions 3.x | parte 1

E aproveito este espaço para um convite… Que tal participar do próximo treinamento online promovido pelo Azure na Prática e que acontecerá durante o dia 29/08/2020 (sábado), tendo como foco Serverless + Azure Functions e que engloba ainda o uso de tecnologias como Azure Logic Apps, RabbitMQ, Apache Kafka, SQL Server, MongoDB, Redis, Application Insights, Azure Cosmos DB e GitHub Actions? Acesse então o link a seguir para efetuar sua inscrição com o desconto especial de pré-venda (apenas R$ 200,00):

https://bit.ly/anp-serverless3-blog-groffe-pre

.NET Core + Serverless: Dicas e Truques com Azure Functions 3.x | Parte 1 [Vídeo]

.NET Core + Serverless: Dicas e Truques com Azure Functions 3.x | Parte 2 [Vídeo]

Acesso a dados com Dapper e Dapper.Contrib

Embora com limitações quando comparado a alternativas mais sofisticadas de acesso a dados relacionais (como o Entity Framework e o FluentNHibernate), o micro-ORM Dapper ainda assim desfruta de grande popularidade entre desenvolvedores .NET. Entre as razões que contribuem para isso estão a alta performance que o mesmo propicia, sobretudo na execução de queries mais complexas.

Deve-se lembrar também do Dapper.Contrib (projeto open source dos mesmos criadores do Dapper), com extensões adicionais que simplificam operações de CRUD, de maneira a dispensar a inclusão de expressões SQL (SELECT, INSERT, UPDATE e DELETE) em código C#.

Para utilizar essas bibliotecas em um projeto baseado em Azure Functions basta alterar o arquivo .csproj correspondente, ou ainda adicionar via linha de comando os packages Dapper ou Dapper.Contrib (este último possui a biblioteca Dapper como dependência).

Na listagem a seguir temos um exemplo de projeto em que foi adicionado o package Dapper.Contrib, além do novo provider de acesso a dados do SQL Server (Microsoft.Data.SqlClient):

Na classe AcoesRepository temos 2 métodos:

  • Save, que faz uso do Dapper.Contrib para a gravação de dados de ações em uma tabela do SQL Server;
  • GetAll, que utiliza o método Query da biblioteca Dapper com o retorno de uma consulta SQL convertido em objetos do tipo Acao.

Importante destacar que a classe Acao foi ajustada, de forma a simplificar a inclusão de dados através do Dapper.Contrib:

  • No atributo Table indicamos a tabela à qual se refere o tipo Acao;
  • O atributo Key deve ser utilizado em campos autoincremento (neste exemplo temos Id).

A Function AcoesServiceBusTopicTrigger está vinculada a um tópico do Azure Service Bus, acessando o método Save de AcoesRepository para a gravação de cotações de ações:

Já a Function Acoes utiliza o método GetAll, também definido em AcoesRepository:

Os fontes deste projeto já estão disponíveis no GitHub:

.NET Core + Azure Functions 3.x + Azure Service Bus (Topic) + SQL Server + Dapper + HTTP Trigger + Cotações de Ações

Disponibilizei também no GitHub outros exemplos de utilização de Dapper com Azure Functions:

.NET Core + Azure Functions 3.x + Azure Cosmos DB + CosmosDBTrigger + Redis + SQL Server + Dapper + Consolidação de Dados de Ações (Compra/Venda)

.NET Core + Azure Functions 3.x + Blob Storage + SQL Server + Dapper.Contrib + Carga de Arquivos

.NET Core + Azure Functions 3.x + Queue Storage + Azure SQL/SQL Server + Queue Trigger + HTTP Trigger + Dapper.Contrib + Cadastro de Produtos + FluentValidation

.NET Core + Azure Functions 3.x + Queue Storage + Azure SQL/SQL Server + Queue Trigger + HTTP Trigger + Dapper.Contrib + Cadastro de Produtos

.NET Core + Azure Functions 3.x + Queue Storage + Azure SQL/SQL Server + Queue Trigger + HTTP Trigger + Dapper.Contrib

Validações com FluentValidation

O FluentValidation é uma alternativa para validação muito popular entre Desenvolvedores .NET, sobretudo no desenvolvimento Web baseado em ASP.NET Core. Podemos também tirar proveito desta solução em aplicações serverless construídas com Azure Functions, bastando para isto adicionar o package FluentValidation aos projetos correspondentes:

Retomando como exemplo o projeto descrito na seção anterior temos a classe DadosAcao, que conterá dados com a cotação de ações e que serão recebidos via tópico do Azure Service Bus:

Um Validator chamado AcaoValidator foi definido, com tal implementação estando baseada em AbstractValidator (namespace FluentValidation) e referenciando a classe DadosAcao:

O tipo AcaoValidator será então instanciado na Function AcoesServiceBusTopicTrigger, com a chamada ao método Validate validando os dados do objeto baseado no tipo DadosAcao:

Lembrando que o código já se encontra no GitHub:

.NET Core + Azure Functions 3.x + Azure Service Bus (Topic) + SQL Server + Dapper + HTTP Trigger + Cotações de Ações

Além de outros exemplos que criei e que empregam FluentValidation para validações:

.NET Core + Azure Functions 3.x + Queue Storage + Azure SQL/SQL Server + Queue Trigger + HTTP Trigger + Entity Framework Core + FluentValidation

.NET Core + Azure Functions 3.x + Queue Storage + Azure SQL/SQL Server + Queue Trigger + HTTP Trigger + Dapper.Contrib + Cadastro de Produtos + FluentValidation

.NET Core + Azure Functions 3.x + Queue Storage + Azure SQL/SQL Server + Queue Trigger + HTTP Trigger + FluentNHibernate

Acesso a dados com Entity Framework Core

Para tirar proveito do Entity Framework Core em implementações baseadas em Azure Functions precisaremos também configurar o uso do injeção de dependências em projeto desse tipo. Este tema já foi abordado no primeiro post desta série e também no artigo:

.NET Core + Serverless: utilizando injeção de dependências com Azure Functions

Um provider para uso do Entity Framework Core deverá ser adicionado à Function App. Se estiver utilizando o SQL Server, acrescente o package Microsoft.EntityFrameworkCore.SqlServer ao projeto:

Na classe Startup deverá ser acionado o método AddEntityFrameworkSqlServer, a fim de se configurar a utilização conjunta do Entity Framework Core com SQL Server:

A seguir temos a implementação da classe MoedasContext implementada para este exemplo:

E do tipo Cotacao:

A Function CotacoesHttpTrigger exemplifica o uso do Entity Framework Core via classe Context (no caso MoedasContext):

  • A dependência para MoedasContext será resolvida via injeção de dependência no construtor de CotacoesHttpTrigger;
  • No método Run utilizamos essa instância de MoedasContext para a execução de uma consulta baseada em LINQ.

Temos ainda um segundo exemplo com a Function MoedasQueueTrigger:

O código deste projeto de exemplo já foi disponibilizado no GitHub:

.NET Core + Azure Functions 3.x + Queue Storage + Azure SQL/SQL Server + Queue Trigger + HTTP Trigger + Entity Framework Core

Deixo aqui também o link com outros exemplos de utilização de Entity Framework Core com Azure Functions:

.NET Core + Azure Functions 3.x + Queue Storage + Azure SQL/SQL Server + Queue Trigger + HTTP Trigger + Entity Framework Core + FluentValidation

.NET Core + Azure Functions 3.x + Queue Storage + Queue Trigger + HTTP Trigger + Entity Framework Core InMemory

--

--

Renato Groffe
Azure na Pratica

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