
Versículo chave: "Consagre ao Senhor tudo o que você faz, e os seus planos serão bem-sucedidos." - Provérbios 16:3
Desenvolvedor de software especializado no ecossistema .NET, atuando com C#, ASP.NET Core e arquiteturas modernas focadas em qualidade, escalabilidade e manutenibilidade. Experiência sólida em Clean Architecture, SOLID, Design Patterns, DDD, CQRS e observabilidade aplicada a microsserviços com mensageria e APIs REST/GraphQL. Atuação completa no ciclo de entrega, envolvendo front-end moderno, testes automatizados, CI/CD, cloud (Azure, AWS, GCP) e monitoramento de aplicações em produção.
Desenvolvedor de software com experiência multidisciplinar e especialista no ecossistema .NET, incluindo C#, ASP.NET Core, Entity Framework Core e ferramentas modernas como SignalR e gRPC.
Tenho experiência sólida em boas práticas com os princípios SOLID, DRY, KISS, TDA e SoC, aplicação de design patterns (criacionais, estruturais e comportamentais), além da adoção de princípios de Clean Code e Clean Architecture para garantir a melhor estrutura, legibilidade, manutenibilidade e escalabilidade do código.
No front-end, atuo em projetos com SPAs (React, Angular, Blazor), SSR (Next.js) e design responsivo com HTML/CSS, Flexbox e CSS Grid, baseados em protótipos do Figma (UI/UX).
Na parte de back-end, construo APIs RESTful e GraphQL com ASP.NET Core, usando padrões como CQRS, MediatR e DDD. Tenho domínio de Git e atuação colaborativa com pipelines de CI/CD (GitHub Actions, Azure DevOps), análise estática de código com SonarQube, testes unitários e de integração com xUnit, Moq e Testcontainers.
Também aplico práticas de observabilidade como métricas com Prometheus/Grafana e logs estruturados com NLog e Serilog ou Elastic Stack, em arquiteturas baseadas em microsserviços e mensageria com RabbitMQ ou Azure Service Bus.
Além disso, implemento ferramentas de analytics como Google Analytics 4 ou Application Insights para monitoramento de usabilidade, funcionalidades e comportamento dos usuários em produção. Tenho experiência com entrega contínua em ambientes PaaS e uso de recursos de nuvem como Azure, AWS e Google Cloud.
- https://medium.com/@shahedbd/complete-net-developer-roadmap-a956ac934047?source=email-afeafff77325-1699595564672-digest.reader--a956ac934047----6-98------------------2c4d77a2_af61_4746_ba5e_d672f0567ad9-1
- https://medium.com/@maherz/10-functional-programming-tips-every-c-developer-should-know-a35f9ea67dfd?source=email-afeafff77325-1699595564672-digest.reader--a35f9ea67dfd----1-109------------------2c4d77a2_af61_4746_ba5e_d672f0567ad9-1
- https://medium.com/@alexvc/net-c-fundamentals-for-senior-devs-a4c46cec2d93?source=email-afeafff77325-1697176799007-digest.reader--a4c46cec2d93----0-98------------------21db751b_aa12_4c21_9185_c81d1d5c1508-1
- https://medium.com/@talktorahul.b/roadmap-to-become-a-pro-web-developer-741ad2442989?source=email-afeafff77325-1697176799007-digest.reader--741ad2442989----4-109------------------21db751b_aa12_4c21_9185_c81d1d5c1508-1
- https://medium.com/@abhisheksinghjava/10-rest-api-best-practices-cd12e3904d00?source=email-afeafff77325-1697176799007-digest.reader-d3a191ac6ed-cd12e3904d00----7-98------------------21db751b_aa12_4c21_9185_c81d1d5c1508-1
- https://medium.com/@gustavorestani/the-most-used-design-patterns-in-net-development-80d76f9fb6b?source=email-afeafff77325-1697349547247-digest.reader--80d76f9fb6b----2-98------------------75f6e6b9_c14e_4507_a092_5cfd13988a83-1
- https://medium.com/@mattbentley_67939/ultimate-net-project-setup-with-clean-architecture-and-domain-driven-design-3bf9e8173420?source=email-afeafff77325-1697349547247-digest.reader-5517fd7b58a6-3bf9e8173420----0-102------------------75f6e6b9_c14e_4507_a092_5cfd13988a83-1
- https://medium.com/@v.cheshmi/introduction-ae32b9f32ac5?source=email-afeafff77325-1698215129862-digest.reader--ae32b9f32ac5----10-98------------------967cd37c_61f7_416e_90cf_c42ed9148e5c-1
- https://medium.com/@rahulsahay19/creating-net-core-microservices-using-clean-architecture-d229d1683ec9?source=email-afeafff77325-1698473490513-digest.reader-d1baaa8417a4-d229d1683ec9----9-98------------------067f8009_6657_46ec_970c_5486c9fe0f99-1
- https://medium.com/@edin.sahbaz/a-demo-on-clean-architecture-with-cqrs-and-repository-pattern-in-net-web-api-986838191e74?source=email-afeafff77325-1698473490513-digest.reader--986838191e74----5-98------------------067f8009_6657_46ec_970c_5486c9fe0f99-1
- https://medium.com/@mattbentley_67939/a-simple-event-sourcing-implementation-in-net-b53c40401ecb?source=email-afeafff77325-1698905016499-digest.reader-5517fd7b58a6-b53c40401ecb----1-108------------------bd54f64e_8d5a_454d_a7bd_2007552b92c5-1
- https://medium.com/@iammanolov98/software-interview-question-task-vs-thread-in-net-d5d3b805eaf3?source=email-afeafff77325-1699078849942-digest.reader--d5d3b805eaf3----9-98------------------d4c473e7_399d_4fac_aa43_247b373950f8-1
- https://medium.com/@juanal98/the-linq-bible-in-c-from-basics-to-best-practices-%EF%B8%8F-518f6ed9f2c4?source=email-afeafff77325-1699078849942-digest.reader-14ffaa42dc34-518f6ed9f2c4----8-102------------------d4c473e7_399d_4fac_aa43_247b373950f8-1
- https://medium.com/@rahulsahay19/comparing-net-ef-core-and-dapper-a-developers-guide-6b14122ac3f5?source=email-afeafff77325-1699078849942-digest.reader--6b14122ac3f5----3-98------------------d4c473e7_399d_4fac_aa43_247b373950f8-1
- https://medium.com/@dheeraj-opensource/complete-example-of-clean-architecture-in-c-and-net-core-7-aff8f2224dfc?source=email-afeafff77325-1699165641721-digest.reader--aff8f2224dfc----3-98------------------0967ca29_e4f3_44be_b575_249fddf44e7a-1
- https://medium.com/@edsondiasalves/start-using-c-records-for-dtos-instead-of-regular-classes-1f84bd5997ca?source=email-afeafff77325-1699165641721-digest.reader-29038077e4c6-1f84bd5997ca----2-99------------------0967ca29_e4f3_44be_b575_249fddf44e7a-1
- https://medium.com/@maherz/10-functional-programming-tips-every-c-developer-should-know-a35f9ea67dfd?source=email-afeafff77325-1699595564672-digest.reader--a35f9ea67dfd----1-109------------------2c4d77a2_af61_4746_ba5e_d672f0567ad9-1
- https://medium.com/@rahulsahay19/creating-net-core-microservices-using-clean-architecture-d229d1683ec9?source=email-afeafff77325-1700202784055-digest.reader-d1baaa8417a4-d229d1683ec9----2-98------------------034a5966_a695_4f4f_bd91_f09b453e9c42-1
- https://medium.com/@craftingcode/how-to-implement-cqrs-pattern-with-rabbitmq-in-microservices-architecture-18c2ba99a9d3?source=email-afeafff77325-1700288546060-digest.reader-d1baaa8417a4-18c2ba99a9d3----1-98------------------2984896d_fd8c_4444_a438_f1a39d8911ac-1
- https://medium.com/@chrlschn/net-source-generators-with-net-7-a68f29b46e74?source=email-afeafff77325-1700376010853-digest.reader-4e2c1156667e-a68f29b46e74----9-99------------------66987f2b_968a_4b95_ae4a_97446a49848e-1
- https://medium.com/@mareks-082/keyed-service-dependency-in-net-8-20a1c9d08e48?source=email-afeafff77325-1700462369454-digest.reader--20a1c9d08e48----0-108------------------0dd777d9_c1ce_47ed_b8fe_e1fb2d84939d-1
- https://medium.com/@mcansener/comparing-soap-and-rest-services-in-c-875ed7f8c1eb?source=email-afeafff77325-1700462369454-digest.reader-d1baaa8417a4-875ed7f8c1eb----12-98------------------0dd777d9_c1ce_47ed_b8fe_e1fb2d84939d-1
- https://medium.com/@rahulsahay19/best-practices-for-using-async-await-in-c-with-net-core-b067ea3fa9d3?source=email-afeafff77325-1700806905610-digest.reader-d1baaa8417a4-b067ea3fa9d3----0-98------------------03c2617f_4c16_4ad2_be67_c9175060addc-1
- https://medium.com/@maherz/how-i-built-a-passive-income-using-c-and-ai-5362d627fe32?source=email-afeafff77325-1700979678471-digest.reader--5362d627fe32----12-109------------------7bea03e5_712a_4a4f_83db_79547ec0a43d-1
- https://medium.com/@craftingcode/how-to-implement-cqrs-pattern-with-rabbitmq-in-microservices-architecture-18c2ba99a9d3?source=email-afeafff77325-1700979678471-digest.reader-d1baaa8417a4-18c2ba99a9d3----1-98------------------7bea03e5_712a_4a4f_83db_79547ec0a43d-1
- https://medium.com/@maherz/how-i-built-a-passive-income-using-c-and-ai-5362d627fe32?source=email-afeafff77325-1700979678471-digest.reader--5362d627fe32----12-109------------------7bea03e5_712a_4a4f_83db_79547ec0a43d-1
- https://medium.com/@ramyelnaghy/use-c-record-instead-of-dto-classes-0aad040aa500?source=email-afeafff77325-1701326630711-digest.reader--0aad040aa500----10-98------------------9202cf9e_cce2_4307_818b_cee335be8634-1
- https://medium.com/@minafrzli/net-developer-interview-questions-6ee3b388c069?source=email-afeafff77325-1705821638795-digest.reader--6ee3b388c069----5-98------------------62abf080_0f57_4cd2_b7b0_56214c9ae355-1
- https://medium.com/@sena.kilicarslan/using-refit-in-net-0843bb199987?source=email-afeafff77325-1705909235619-digest.reader-9864284e8ea3-0843bb199987----8-98------------------aa681753_8d3e_4bd1_bc85_51aa954d5ba4-1
- https://medium.com/@mabroukmahdhi/5-big-mistakes-c-developers-often-make-in-their-code-c317a0d07011?source=email-afeafff77325-1705909235619-digest.reader--c317a0d07011----14-98------------------aa681753_8d3e_4bd1_bc85_51aa954d5ba4-1
- https://medium.com/@merwan01/c-threads-asynchronous-programming-79b5d8d787d5?source=email-afeafff77325-1705909235619-digest.reader-4e55b18cd443-79b5d8d787d5----5-98------------------aa681753_8d3e_4bd1_bc85_51aa954d5ba4-1
- https://medium.com/@merwan01/c-threads-asynchronous-programming-79b5d8d787d5?source=email-afeafff77325-1705909235619-digest.reader-4e55b18cd443-79b5d8d787d5----5-98------------------aa681753_8d3e_4bd1_bc85_51aa954d5ba4-1
- https://medium.com/@mabroukmahdhi/5-big-mistakes-c-developers-often-make-in-their-code-c317a0d07011?source=email-afeafff77325-1705909235619-digest.reader--c317a0d07011----14-98------------------aa681753_8d3e_4bd1_bc85_51aa954d5ba4-1
- https://medium.com/@mostafaelnady1997/apache-kafka-in-net-7-afd16bfb56eb?source=email-afeafff77325-1700633196668-digest.reader--afd16bfb56eb----10-98------------------784f10db_fc57_455a_ba9e_413df2b6ba04-1
![]() |
![]() |
Microsoft iniciou nos anos 70 criando linguagens de programação: Basic. Nos anos 80, surge o DOS, que foi utilizado como OS padrão para computadores IBM. Nos próximos anos a Microsoft atua fortemente na criação do OS Windows.
1997, No fim dos anos 90, a Microsoft tentou consolidar as ferramentas de desenvolvimento (IDEs e runtimes) com o Visual Studio 97:
- Visual Basic 5
- Visual FoxPro 5
- C++ 5
- J++
1998, lançamento do Visual Studio 6:
- Visual Basic 6
- Visual FoxPro 6
- C++ 6
- J++ 6
A linguagem C# ou também C-Sharp, é uma linguagem de programação de alto-nível e orientada a objetos. C# (pronunciado "C sharp") é uma linguagem de programação moderna, orientada a objetos e fortemente tipada, desenvolvida pela Microsoft como parte da plataforma .NET. Foi criada no início dos anos 2000 e rapidamente se tornou uma das linguagens mais populares para o desenvolvimento de aplicações de desktop, web, móveis e jogos.
As principais características do C# é que ele é uma linguagem de programação com orientação a objetos (OOP), a sintaxe do C# lembra a sintaxe do JavaScript, Java e C++. Portanto, suporta a criação e manipulação de classes e objetos. Permite os cinco pilares da programação orientada a objetos, a criação de classes derivadas que herdam características de classes base. Permite que métodos em classes derivadas tenham comportamentos diferentes. Permite esconder os detalhes internos de uma classe e expor apenas as funcionalidades essenciais.
Base para construção de aplicações corporativas, web, desktop, mobile, jogos e IoT. Ambiente unificado para alta produtividade, desempenho confiável e compatibilidade com diferentes sistemas e dispositivos. A tipagem forte e estática, os tipos das variáveis são definidos em tempo de compilação e não podem ser alterados. Com verificação de tipos em tempo de compilação, os erros de tipo são detectados em tempo de compilação, o que reduz erros em tempo de execução.
Sintaxe e Semântica Modernas:
- Legibilidade: A sintaxe é clara e intuitiva, facilitando a leitura e escrita do código.
- Características Funcionais: Suporta programação funcional com expressões lambda, LINQ (Language Integrated Query) e delegados.
Possui suporte à Programação Assíncrona, utilizando Async e Await, facilita a escrita de código assíncrono, melhorando a performance e a capacidade de resposta das aplicações.
A Plataforma .NET (Dot Net) é a biblioteca de Classes Base proporciona uma vasta biblioteca de classes que facilita o desenvolvimento de uma ampla gama de aplicações. O .NET Framework é uma plataforma de desenvolvimento criada pela Microsoft em 2002, que fornece um ambiente de execução para aplicações e serviços, permitindo que desenvolvedores construam e executem aplicações de forma consistente.
Ele inclui uma grande biblioteca de classes (Framework Class Library - FCL) e uma máquina virtual conhecida como Common Language Runtime (CLR) que é o ambiente de execução do código, gerencia a execução do código, garbage collection, memória e segurança; incluía a Base Class Library (BCL) que é o conjunto de bibliotecas para manipulação de arquivos, banco de dados, redes e segurança, que oferece serviços como gerenciamento de memória, segurança, e exceção.
A linguagem C# foi desenvolvida especificamente para o .NET Framework e é uma das linguagens de programação mais proeminentes para o desenvolvimento de aplicações na plataforma .NET. C# foi desenhada para aproveitar ao máximo os recursos oferecidos pelo .NET, incluindo o CLR, FCL e outras funcionalidades.
Possui linguagens integradas como C#, F#, Visual Basic e outras interoperam via Common Language Specification (CLS). Bibliotecas e APIs extensas - Base Class Library e pacotes NuGet para autenticação, criptografia, nuvem e muito mais.
O código C# é compilado para Intermediate Language (IL), que é então executado pelo CLR. Isso permite que o código C# seja executado em qualquer plataforma que suporte o CLR. Graças ao CTS e CLS, C# pode interoperar facilmente com outras linguagens .NET como VB.NET e F#. As funcionalidades da Linguagem incluem:
-
Suporte Nativo: Muitas das funcionalidades avançadas do .NET, como LINQ (Language Integrated Query), manipulação assíncrona com
asynceawait, e expressões lambda, são diretamente suportadas e integradas em C#. -
Atualizações e Evoluções: A evolução do C# e do .NET Framework acontece de forma coordenada, garantindo que novas funcionalidades do framework possam ser utilizadas de forma eficaz pela linguagem.
Principais Componentes do .NET Framework:
-
Common Language Runtime (CLR):
- Máquina Virtual: O CLR é o ambiente de execução do .NET que gerencia a execução de programas escritos em diversas linguagens de programação.
- Gerenciamento de Memória: Inclui coleta de lixo automática, que gerencia a alocação e desalocação de memória.
- Segurança e Isolamento: Implementa políticas de segurança e isolamento de aplicativos, proporcionando um ambiente de execução seguro.
-
Framework Class Library (FCL):
- Biblioteca de Classes: Uma extensa biblioteca de classes reutilizáveis que fornece suporte para manipulação de dados, acesso a bancos de dados, entrada/saída, gráficos, e desenvolvimento de interfaces de usuário.
- APIs Consistentes: Oferece APIs consistentes e fáceis de usar para realizar tarefas comuns.
-
Common Type System (CTS): Sistema de Tipos: Define todos os tipos de dados e as regras para a definição e uso desses tipos no .NET, garantindo interoperabilidade entre linguagens.
-
Common Language Specification (CLS): Especificação de Linguagem: Conjunto de regras que linguagens de programação devem seguir para serem compatíveis com o .NET, facilitando a interoperabilidade.
Ferramentas e IDEs: Visual Studio é o ambiente de desenvolvimento integrado (IDE) da Microsoft, Visual Studio, oferece um suporte extensivo para desenvolvimento com C# e .NET, incluindo ferramentas de depuração, designers visuais, e integração contínua. As ferramentas mais utilizadas são: Console Application, Windows Forms Application
Versões do .NET: A plataforma .NET evoluiu ao longo dos anos e agora está disponível em diferentes formas:
-
.NET Framework: A versão original, destinada principalmente ao desenvolvimento de aplicações Windows.
-
.NET Core: Uma versão cross-platform e open-source do .NET, que permite desenvolvimento para Windows, macOS e Linux. Com o .NET Core (agora .NET 5+), C# pode ser usado para desenvolver aplicações que rodam em Windows, Linux e macOS.
-
.NET 5+: A versão unificada que combina os melhores aspectos do .NET Framework, .NET Core e Xamarin, .NET MAUI (mobile) e Unity (jogos) proporcionando um ambiente de desenvolvimento consistente para todas as plataformas.
O .NET Framework é uma plataforma poderosa e abrangente para desenvolvimento de software, e a linguagem C# é sua principal linguagem de programação. Juntos, eles oferecem uma base robusta para construir aplicações seguras, eficientes e de alto desempenho. A integração profunda entre C# e o .NET permite que desenvolvedores aproveitem ao máximo os recursos oferecidos pela plataforma, facilitando o desenvolvimento e a manutenção de aplicações complexas.
- Segurança: Mecanismos de Segurança: Oferece diversas características de segurança como controle de acesso, exceções e gerenciamento automático de memória com garbage collection.
Aplicações Comuns:
-
Desenvolvimento Web: ASP.NET: Framework para a construção de aplicações web dinâmicas e serviços web.
-
NuGet: O NuGet é um gerenciador de pacotes desenvolvido pela Microsoft, projetado para o ecossistema .NET. Ele serve para facilitar a adição, instalação, atualização e distribuição de dependências e ferramentas em projetos .NET.
-
Aplicações de Desktop: Windows Forms e WPF (Windows Presentation Foundation): Para criar aplicações desktop ricas para Windows.
-
Desenvolvimento Móvel: Xamarin: Plataforma para o desenvolvimento de aplicações móveis cross-platform usando C#.
-
Desenvolvimento de Jogos: Unity: Um dos motores de jogos mais populares que usa C# como linguagem de script.
-
Serviços Web e APIs: Web API: Para a construção de APIs RESTful.
Mostra a aplicação do dotnet funcionando e suas opções:
dotnetMostra a versão instalada do seu dotnet:
dotnet --versionLista todos os pacotes do sdk instalados na sua máquina:
dotnet --list-sdksPara adicionar o pacote com dotnet:
dotnet add package [pacote]Para rodar um programa direto no console do terminal:
dotnet run Program.csAqui está um exemplo simples de um programa em C# que imprime "Hello, World!" na console (Abra o Visual Studio Community > Console Application):
using System; // Diretiva de uso em C#
namespace HelloWorld // Escopo para um conjunto de classes, interfaces, structs, enums e outros tipos.
{
class Program // Classe do nosso arquivo: Program.cs
{
static void Main(string[] args) // Método chamado quando o programa é iniciado e é responsável por executar o código principal.
{
Console.WriteLine("Hello, World!"); // Código principal: Exibir no console em uma linha = "Hello, World!"
}
}
}No código C#, o namespace HelloWorld é uma forma de organizar e estruturar o código. Um namespace é uma declaração que define um escopo para um conjunto de classes, interfaces, structs, enums e outros tipos. O namespace HelloWorld nesse código serve para:
- Organizar o código: Agrupa classes e outros tipos relacionados.
- Evitar conflitos: Impede que classes com o mesmo nome sejam confundidas.
- Facilitar a referência: Permite que outras partes do código acessem as classes e tipos definidos dentro do namespace.
Nesse caso específico, o namespace HelloWorld contém a classe Program, que por sua vez contém o método Main, onde o programa é executado.
O static void Main(string[] args) é o ponto de entrada de um programa C#. Esse método é chamado quando o programa é iniciado e é responsável por executar o código principal. Os parâmetros string[] args representa os argumentos de linha de comando passados para o programa. As características:
static: O método pode ser chamado sem criar uma instância da classe.void: O método não retorna nenhum valor.
Nesse caso, o método Main contém a instrução Console.WriteLine("Hello, World!");, que imprime a mensagem "Hello, World!" no console.
Em C#, using é uma diretiva que permite importar namespaces e utilizar classes e métodos sem precisar qualificar totalmente o nome. A diretiva using serve para:
- Importar namespaces: Permitindo o uso de classes e métodos sem precisar especificar o namespace completo.
- Evitar repetição: Reduzindo a necessidade de escrever o nome completo do namespace.
Com a diretiva using System;, você pode utilizar Console.WriteLine em vez de System.Console.WriteLine. A diretiva using ajuda a:
- Simplificar o código: Reduzindo a verbosidade e melhorando a legibilidade.
- Melhorar a produtividade: Permitindo que você se concentre na lógica do programa em vez de se preocupar com nomes completos.
A linha using System; é uma diretiva de uso em C#. Essa diretiva permite que você use classes e métodos do namespace System sem precisar qualificar totalmente o nome. Ele não é obrigatório em todos os casos, using System; é uma diretiva útil para evitar a repetição de nomes qualificados, mas não é estritamente necessária se você estiver disposto a utilizar os nomes completos.
Com essa diretiva, você pode:
- Usar classes e métodos: Acessar classes como
Console,String,DateTime, etc. - Evitar nomes qualificados: Não precisa escrever
System.Console.WriteLine, por exemplo.
Exemplo: Nesse caso, a diretiva using System; permite que você use Console.WriteLine em vez de System.Console.WriteLine. Se você não incluir using System;, pode utilizar o nome qualificado completo, como:
System.Console.WriteLineSystem.String.FormatSystem.DateTime.Now
Esse acima é o modelo base, por padrão, o IDE Visual Studio nos apresenta dessa forma:
using System; // Diretiva de uso em C#
using System.Collections.Generic; // fornece classes e interfaces para trabalhar com coleções genéricas.
using System.Linq; // utilize métodos de extensão LINQ (Language Integrated Query) para trabalhar com coleções de dados.
using System.Text; // permite que você utilize classes e métodos relacionados a manipulação de strings e texto.
using System.Threading.Tasks; // utilize classes e métodos relacionados a programação assíncrona e paralela.
namespace HelloWorld
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World");
}
}
}Covariância e Contravariância
// Covariância ✅
// Permite tipos derivados
IEnumerable<string> strings = ["hello", "world"];
IEnumerable<object> objects = strings;
// Contravariância ✅
// Permit tipos base
Action<object> objectAction = obj => Console.Write(obj);
Action<string> stringAction = objectAction;A instrução switch básica em C# avalia uma expressão e executa o bloco de caso correspondente. Inclui a palavra-chave seguida pela expressão entre parênteses e uma série de rótulos.switch case
int number = 2;
switch (number)
{
case 1:
Console.WriteLine("Number is 1");
break;
case 2:
Console.WriteLine("Number is 2");
break;
case 3:
Console.WriteLine("Number is 3");
break;
default:
Console.WriteLine("Number is not 1, 2, or 3");
break;
}
// Output: 2 O MSSQL - Microsoft SQL Server é um sistema de gerenciamento de banco de dados relacional (RDBMS) desenvolvido pela Microsoft. Ele é uma das principais plataformas de banco de dados usadas por organizações em todo o mundo para armazenar, manipular e recuperar dados. O Microsoft SQL Server é uma poderosa plataforma de banco de dados relacional amplamente utilizada em organizações de todos os tamanhos para armazenar, manipular e gerenciar dados de forma eficiente e confiável. Com sua robustez, segurança, desempenho e integração com outras tecnologias da Microsoft, o SQL Server continua sendo uma escolha popular para desenvolvedores e administradores de banco de dados em todo o mundo.
O T-SQL (Transact-SQL) é a linguagem de consulta usada no Microsoft SQL Server. Ela é uma extensão do SQL (Structured Query Language) padrão com recursos adicionais específicos do SQL Server. O T-SQL é uma linguagem poderosa que permite aos desenvolvedores e administradores de banco de dados realizar uma ampla variedade de operações, incluindo consultas, manipulação de dados, criação e modificação de objetos de banco de dados, controle de acesso e muito mais.
Principais Recursos do T-SQL:
-
Consulta de Dados: Permite escrever consultas complexas para recuperar dados de tabelas e outras fontes de dados.
-
Manipulação de Dados: Fornece instruções como
INSERT,UPDATE,DELETEpara inserir, atualizar e excluir dados em tabelas. -
Definição de Dados: Possibilita a criação e modificação de objetos de banco de dados, como tabelas, índices, procedimentos armazenados, funções e visões.
-
Controle de Transações: Oferece suporte a transações para garantir a atomicidade, consistência, isolamento e durabilidade das operações no banco de dados.
-
Controle de Fluxo: Permite o uso de estruturas de controle de fluxo, como
IF...ELSE,WHILE,BEGIN...END, para controlar o fluxo de execução do código. -
Tratamento de Exceções: Possibilita o tratamento de erros e exceções usando blocos
TRY...CATCHpara lidar com situações excepcionais de forma controlada. -
Funções e Procedimentos Armazenados: Permite a criação de funções e procedimentos armazenados para encapsular lógica de negócios e reutilizá-la em várias partes do código.
-
Gerenciamento de Segurança: Oferece recursos para controlar o acesso aos objetos do banco de dados usando permissões e papéis de segurança.
Exemplos de T-SQL:
Consulta de Dados:
SELECT FirstName, LastName
FROM Employees
WHERE Department = 'IT'
ORDER BY LastName;Inserção de Dados:
INSERT INTO Products (ProductName, Price)
VALUES ('Smartphone', 999.99),
('Laptop', 1499.99);Atualização de Dados:
UPDATE Customers
SET Email = '[email protected]'
WHERE CustomerID = 123;Exclusão de Dados:
DELETE FROM Orders
WHERE OrderDate < '2022-01-01';Criação de Tabela:
CREATE TABLE Products (
ProductID INT PRIMARY KEY,
ProductName NVARCHAR(100),
Price DECIMAL(10, 2)
);Criação de Procedimento Armazenado:
CREATE PROCEDURE GetCustomerOrders
@CustomerID INT
AS
BEGIN
SELECT * FROM Orders
WHERE CustomerID = @CustomerID;
END;Vantagens do T-SQL:
-
Integração com SQL Server: O T-SQL é otimizado para funcionar com o SQL Server, aproveitando os recursos e funcionalidades específicas da plataforma.
-
Desempenho: Por ser otimizado para o SQL Server, o T-SQL pode oferecer melhor desempenho em comparação com outras linguagens de consulta genéricas.
-
Ampla Gama de Recursos: Oferece uma ampla variedade de recursos e funcionalidades para atender às necessidades complexas de desenvolvimento e administração de banco de dados.
-
Familiaridade: Muitos desenvolvedores e administradores estão familiarizados com o T-SQL devido à sua ampla adoção e documentação disponível.
Voltando ao MSSQL, as principais características dele são:
-
Modelo Relacional: O SQL Server utiliza um modelo relacional para armazenar dados em tabelas, que são organizadas em bancos de dados.
-
Linguagem SQL: Suporte completo à Linguagem de Consulta Estruturada (SQL), que permite aos desenvolvedores e administradores realizar consultas e manipular dados de forma eficiente.
-
Gerenciamento de Dados: Capacidade de armazenar, recuperar e manipular grandes volumes de dados de forma eficiente e confiável.
-
Segurança Integrada: Recursos avançados de segurança, incluindo autenticação, autorização, criptografia e auditoria, para proteger os dados armazenados no banco de dados.
-
Escalabilidade e Desempenho: Suporte a recursos de escalabilidade horizontal e vertical, bem como otimizações de desempenho para garantir um desempenho rápido e responsivo, mesmo em ambientes de alta carga.
-
Replicação e Alta Disponibilidade: Recursos de replicação e clustering para garantir a disponibilidade contínua dos dados e evitar pontos únicos de falha.
-
Integração com Ferramentas Microsoft: Integração nativa com outras ferramentas e tecnologias da Microsoft, como .NET Framework, Visual Studio, Azure e Power BI.
-
Suporte a Plataformas Múltiplas: Disponibilidade em várias plataformas, incluindo Windows e Linux, proporcionando flexibilidade na escolha da plataforma de implantação.
Edições do Microsoft SQL Server:
O SQL Server está disponível em várias edições, cada uma com diferentes conjuntos de recursos e preços adequados a diferentes necessidades e orçamentos:
-
Enterprise: Oferece os recursos mais avançados e escalabilidade para grandes empresas e aplicações críticas.
-
Standard: Adequada para médias empresas e aplicações com requisitos de banco de dados menos exigentes.
-
Developer: Destinada a desenvolvedores para uso em ambientes de desenvolvimento e teste.
-
Express: Edição gratuita e leve, ideal para pequenas aplicações e desenvolvimento.
-
Web: Projetada para hospedagem de sites e aplicações web.
Componentes do SQL Server:
O SQL Server consiste em vários componentes principais, incluindo:
- Database Engine: Responsável pelo armazenamento, processamento e segurança dos dados.
- Analysis Services: Fornece serviços de análise e mineração de dados para tomada de decisões empresariais.
- Integration Services: Facilita a integração de dados entre sistemas heterogêneos.
- Reporting Services: Permite a criação, distribuição e gerenciamento de relatórios.
- Machine Learning Services: Permite a integração de algoritmos de aprendizado de máquina diretamente no banco de dados.
Exemplo de Uso do Microsoft SQL Server:
Aqui está um exemplo simples de criação de uma tabela e inserção de dados usando SQL Server Management Studio (SSMS):
-- Criar uma nova tabela
CREATE TABLE Clientes (
ClienteID INT PRIMARY KEY,
Nome NVARCHAR(100),
Email NVARCHAR(100)
);
-- Inserir dados na tabela
INSERT INTO Clientes (ClienteID, Nome, Email)
VALUES (1, 'João', '[email protected]'),
(2, 'Maria', '[email protected]');Vantagens do Microsoft SQL Server:
-
Robustez e Confiabilidade: Uma plataforma madura e confiável com uma ampla gama de recursos para atender às necessidades de empresas de todos os tamanhos.
-
Desempenho: Oferece otimizações de desempenho para garantir uma resposta rápida mesmo em ambientes de alta carga.
-
Segurança: Recursos avançados de segurança para proteger os dados sensíveis contra ameaças internas e externas.
-
Integração com Ferramentas Microsoft: Integração perfeita com outras ferramentas e tecnologias da Microsoft, facilitando o desenvolvimento e administração de aplicações.
-
Escalabilidade: Capacidade de escalar verticalmente e horizontalmente para lidar com o crescimento dos dados e das demandas da aplicação.
O Apache Cassandra é um sistema de gerenciamento de banco de dados distribuído altamente escalável, projetado para lidar com grandes volumes de dados distribuídos em várias máquinas, oferecendo alta disponibilidade e tolerância a falhas. Ele foi originalmente desenvolvido pelo Facebook e, em 2008, tornou-se um projeto de código aberto sob a incubação da Apache Software Foundation.
Principais Características do Apache Cassandra:
-
Modelo de Dados Desnormalizado: O Cassandra utiliza um modelo de dados de estilo NoSQL, no qual os dados são armazenados de forma desnormalizada, permitindo consultas rápidas e eficientes.
-
Escalabilidade Horizontal: É altamente escalável horizontalmente, o que significa que pode ser facilmente dimensionado adicionando novos nós ao cluster para lidar com o aumento da carga de trabalho e volume de dados.
-
Arquitetura Distribuída: Distribui os dados entre vários nós em um cluster, permitindo que ele mantenha alta disponibilidade e tolerância a falhas mesmo em caso de falha de hardware ou rede.
-
Desempenho e Baixa Latência: Oferece baixa latência e alto desempenho para operações de leitura e gravação, tornando-o adequado para aplicações que exigem resposta rápida.
-
Sem Ponto Único de Falha: Elimina pontos únicos de falha usando uma arquitetura descentralizada, onde cada nó no cluster é igualmente responsável pela execução de consultas e armazenamento de dados.
-
Flexibilidade de Consistência: Permite aos usuários configurar o nível de consistência desejado para operações de leitura e gravação, oferecendo uma escolha entre consistência forte e disponibilidade imediata.
-
Suporte a Consultas Flexíveis: Suporta consultas flexíveis usando CQL (Cassandra Query Language), uma linguagem de consulta semelhante ao SQL, que permite realizar consultas simples e complexas nos dados.
-
Integração com Ferramentas de Big Data: Pode ser integrado com outras ferramentas de big data, como Apache Hadoop e Apache Spark, para análise de dados em larga escala.
Casos de Uso do Apache Cassandra:
-
Aplicações de Redes Sociais: Usado por empresas de redes sociais para armazenar dados de perfil de usuários, feeds de notícias e interações sociais.
-
Aplicações de IoT (Internet das Coisas): Ideal para armazenar grandes volumes de dados gerados por dispositivos IoT, como sensores, medidores e dispositivos conectados.
-
Aplicações de Análise de Logs: Utilizado para armazenar e analisar logs de aplicativos, servidores e sistemas distribuídos devido à sua capacidade de lidar com grande volume de dados e baixa latência.
-
Aplicações de Monitoramento em Tempo Real: Adequado para aplicações que exigem monitoramento em tempo real e análise de dados em tempo real, como detecção de fraudes, monitoramento de desempenho e análise de eventos.
-
Aplicações de Comércio Eletrônico: Usado para armazenar catálogos de produtos, histórico de compras, carrinhos de compras e dados de sessão de usuários em plataformas de comércio eletrônico.
Exemplo de Uso do Apache Cassandra:
Aqui está um exemplo simples de criação de um keyspace e uma tabela usando CQL:
-- Criar um novo keyspace
CREATE KEYSPACE MyKeyspace
WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 3};
-- Usar o keyspace
USE MyKeyspace;
-- Criar uma nova tabela
CREATE TABLE Users (
UserID UUID PRIMARY KEY,
Username TEXT,
Email TEXT
);Vantagens do Apache Cassandra:
-
Escalabilidade Linear: Capacidade de escalar horizontalmente para lidar com grandes volumes de dados e carga de trabalho, sem degradação no desempenho.
-
Alta Disponibilidade: Oferece alta disponibilidade e tolerância a falhas, garantindo que os dados permaneçam acessíveis mesmo em caso de falha de hardware ou rede.
-
Desempenho e Baixa Latência: Fornece baixa latência e alto desempenho para operações de leitura e gravação, mesmo em ambientes distribuídos.
-
Modelo de Dados Flexível: Suporta um modelo de dados flexível, permitindo a adição de novas colunas e a atualização de esquemas sem interrupções.
-
Comunidade Ativa e Suporte: Tem uma comunidade ativa de usuários e desenvolvedores, além de suporte comercial disponível por meio de fornecedores e provedores de serviços.
https://maherz.medium.com/10-must-know-c-code-smells-and-how-to-fix-them-9b9310c5f809 https://maherz.medium.com/top-10-performance-optimization-tips-for-c-developers-3b09d2385e54?source=post_page---author_recirc--9b9310c5f809----2---------------------3b6ba5d1_af1f_4367_a5c2_412dbd6827fb--------------
O Windows Forms Application (Aplicação em janela para formulários), frequentemente referida como WinForms, é uma plataforma de desenvolvimento de aplicativos gráficos baseada no Windows, fornecida pelo .NET Framework. Introduzida pela Microsoft, ela permite a criação de interfaces de usuário (UI) ricas e baseadas em eventos para aplicativos de desktop.
Windows Forms é uma plataforma robusta e fácil de usar para o desenvolvimento de aplicações desktop no Windows. Ideal para criar interfaces de usuário rapidamente e integrar com o .NET Framework, continua sendo uma escolha popular para muitos desenvolvedores, especialmente em manutenção de software legado e projetos internos corporativos.
Características Principais do Windows Forms:
-
Controles de UI: WinForms oferece uma ampla gama de controles de interface do usuário, como botões, caixas de texto, labels, grids, listas, e muito mais, que podem ser facilmente arrastados e soltos no formulário durante o design.
-
Design Visual: Utiliza um designer visual no Visual Studio, permitindo aos desenvolvedores arrastar e soltar componentes de UI no formulário e configurar suas propriedades visualmente.
-
Eventos e Manipulação de Eventos: Baseado em um modelo de programação orientado a eventos, onde ações do usuário, como cliques de botão e entradas de teclado, disparam eventos que podem ser manipulados por código.
-
Integração com .NET Framework: Aproveita o poder do .NET Framework para acessar bibliotecas e funcionalidades como acesso a dados, redes, manipulação de arquivos, e mais.
-
Customização e Estilização: Permite a personalização extensa dos controles e do formulário através de propriedades, herança de classes, e sobrecarga de métodos de desenho.
-
Suporte ao Legacy: É uma tecnologia madura, amplamente utilizada para a manutenção e desenvolvimento de aplicativos de desktop herdados.
Estrutura de um Windows Forms Application: Um aplicativo WinForms típico consiste em uma ou mais janelas ou "forms". Cada form é representado por uma classe que herda de System.Windows.Forms.Form.
Exemplo Básico: Aqui está um exemplo simples de uma aplicação Windows Forms que exibe uma mensagem "Hello, World!" quando um botão é clicado.
-
Criação do Formulário: Primeiro, você cria um novo projeto Windows Forms Application no Visual Studio.
-
Adicionar Controles: No designer, arraste um
Buttonda Toolbox para o formulário. -
Configurar Eventos: Clique duas vezes no botão para gerar o evento
Clicke escrever o código.
Código do Formulário:
Form1.cs:
using System;
using System.Windows.Forms;
public class Form1 : Form
{
private Button button1;
public Form1()
{
// Inicialização do botão
button1 = new Button();
button1.Size = new System.Drawing.Size(100, 50);
button1.Location = new System.Drawing.Point(100, 100);
button1.Text = "Click Me";
button1.Click += new EventHandler(button1_Click);
// Adicionar o botão ao formulário
Controls.Add(button1);
}
// Manipulador de eventos para o clique do botão
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show("Hello, World!");
}
[STAThread]
public static void Main()
{
Application.EnableVisualStyles();
Application.Run(new Form1());
}
}Vantagens do Windows Forms:
-
Facilidade de Uso: O designer visual e a ampla gama de controles tornam a criação de interfaces de usuário rápida e intuitiva.
-
Integração com Visual Studio: Ferramentas poderosas e recursos de depuração do Visual Studio.
-
Maturidade: Tecnologia bem estabelecida com uma grande comunidade de desenvolvedores e muitos recursos disponíveis.
-
Desempenho: Adequado para aplicativos de desktop que requerem interações rápidas e responsivas.
Limitações do Windows Forms:
-
Plataforma Específica: Funciona apenas no ambiente Windows.
-
Design Responsivo Limitado: Menos suporte para design responsivo e moderno em comparação com tecnologias mais recentes como WPF (Windows Presentation Foundation) ou UWP (Universal Windows Platform).
-
Tecnologia Legada: Embora ainda seja suportada, não é mais o foco principal da Microsoft para novas aplicações de desktop, que agora estão voltadas para WPF e UWP.
LINQ, que significa Language Integrated Query (Consulta Integrada à Linguagem), é uma tecnologia do .NET que permite aos desenvolvedores realizar consultas a coleções de dados de maneira direta e intuitiva usando a sintaxe das linguagens de programação .NET, como C# e VB.NET. Introduzido no .NET Framework 3.5, o LINQ oferece uma forma unificada e consistente de acessar diferentes fontes de dados, incluindo objetos na memória, bancos de dados relacionais, XML e mais.
LINQ é uma poderosa ferramenta dentro do ecossistema .NET, que simplifica a interação com coleções de dados, sejam elas na memória, em bancos de dados, ou em documentos XML. Sua sintaxe expressiva e integração com a linguagem de programação melhora a produtividade e a qualidade do código, tornando-o uma escolha popular entre desenvolvedores .NET para manipulação de dados.
Características Principais do LINQ:
-
Consistência: LINQ oferece uma sintaxe consistente para consultas a diferentes tipos de dados, proporcionando uma experiência uniforme independentemente da fonte de dados.
-
Tipos de Dados Suportados:
- LINQ to Objects: Para coleções na memória, como listas e arrays.
- LINQ to SQL: Para consultas a bancos de dados SQL Server, traduzindo consultas LINQ para SQL.
- LINQ to Entities: Para uso com o Entity Framework, permitindo consultas a bancos de dados relacionais.
- LINQ to XML: Para manipulação e consulta de documentos XML.
- LINQ to DataSet: Para consultas a DataSets em aplicações ADO.NET.
-
Intellisense e Verificação de Tipos: A integração de LINQ com a linguagem de programação permite o uso de Intellisense e verificação de tipos em tempo de compilação, reduzindo erros de sintaxe e melhorando a produtividade do desenvolvedor.
-
Expressividade: A sintaxe de consulta LINQ é expressiva e poderosa, permitindo a realização de operações complexas de filtragem, ordenação, agrupamento e projeção de dados.
Sintaxe de LINQ: LINQ pode ser escrito usando duas sintaxes principais:
-
Sintaxe de Consulta (Query Syntax)
-
Sintaxe de Método (Method Syntax)
Exemplo de LINQ to Objects:
Sintaxe de Consulta:
int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
var evenNumbers = from num in numbers
where num % 2 == 0
select num;
foreach (var num in evenNumbers)
{
Console.WriteLine(num);
}Sintaxe de Método:
int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
var evenNumbers = numbers.Where(num => num % 2 == 0);
foreach (var num in evenNumbers)
{
Console.WriteLine(num);
}Exemplo de LINQ to SQL:
using (var context = new MyDbContext())
{
var query = from product in context.Products
where product.Price > 100
select product;
foreach (var product in query)
{
Console.WriteLine($"{product.Name} - {product.Price}");
}
}Operações Comuns com LINQ:
-
Filtragem:
wherevar result = from item in collection where item.Property == someValue select item;
-
Ordenação:
order byvar result = from item in collection orderby item.Property select item;
-
Projeção:
selectvar result = from item in collection select new { item.Property1, item.Property2 };
-
Agrupamento:
group byvar result = from item in collection group item by item.Property into grouped select grouped;
-
Junções:
joinvar result = from item1 in collection1 join item2 in collection2 on item1.Key equals item2.Key select new { item1, item2 };
Vantagens do LINQ:
-
Produtividade: A sintaxe integrada e intuitiva facilita a escrita e a leitura de consultas.
-
Redução de Erros: Verificação de tipos em tempo de compilação ajuda a reduzir erros de tempo de execução.
-
Consistência: Um único conjunto de habilidades e sintaxe para consultar diferentes fontes de dados.
-
Expressividade: Consultas complexas podem ser expressas de maneira clara e concisa.
Desvantagens do LINQ:
-
Desempenho: Em alguns casos, pode haver impacto no desempenho devido à sobrecarga introduzida pela abstração do LINQ.
-
Curva de Aprendizado: Desenvolvedores que não estão familiarizados com a programação funcional podem encontrar dificuldades para aprender e usar LINQ de maneira eficaz.
-
Dependência do ORM: Para LINQ to SQL ou LINQ to Entities, a performance e a funcionalidade podem ser limitadas pelas capacidades do ORM subjacente.
In the ever-evolving world of software development, C# and the .NET Framework stand as the pillars of robust and scalable application creation. With its extensive range of features and intuitive syntax, mastering C#/NET can revolutionize your projects. In this article, we present 10 carefully selected snippets that will take your coding skills to the next level, ensuring you remain captivated by the beauty of efficient and elegant code.
- Read-Only Collections: Immutable collections are essential for thread-safe operations and ensuring the integrity of your data.
var originalList = new List<string> { "Alice", "Bob", "Charlie" };
var readOnlyCollection = originalList.AsReadOnly();
// readOnlyCollection is now immutable.- Async/Await for Responsive Apps: Use async/await to keep your user interface responsive and operations non-blocking.
public async Task<string> FetchDataAsync(string url)
{
using (var httpClient = new HttpClient())
{
var response = await httpClient.GetStringAsync(url);
return response;
}
}- LINQ Queries: Effortlessly manipulate data using LINQ queries to enhance readability and conciseness.
var scores = new int[] { 97, 92, 81, 60 };
var highScores = from score in scores
where score > 80
select score;
// highScores now contains 97, 92, and 81.- Null-Conditional Operator: Avoid NullReferenceException by using the null-conditional operator for safer null checks.
string[] array = null;
var length = array?.Length ?? 0;
// length is 0 without throwing an exception.- Tuple Deconstruction: Simplify method outputs by returning multiple values using tuples and deconstruction.
public (int, string) GetPerson()
{
return (1, "John Doe");
}
var (id, name) = GetPerson();- ValueTuple for Lightweight Data Structures: Leverage ValueTuple for temporary data structures without defining a full class or struct.
var person = (Id: 1, Name: "Jane Doe");
Console.WriteLine($"{person.Name} has ID {person.Id}");- Pattern Matching: Embrace pattern matching for a more expressive syntax when checking types and values.
object obj = 123;
if (obj is int i)
{
Console.WriteLine($"Integer: {i}");
}- Extension Methods: Enhance the functionality of existing classes without altering their source code.
public static class StringExtensions
{
public static string Quote(this string str)
{
return $"\"{str}\"";
}
}
var myString = "Hello, world!";
Console.WriteLine(myString.Quote());- Using Declarations: Streamline the management of disposable objects with the new using declaration.
using var streamReader = new StreamReader("file.txt");
string content = streamReader.ReadToEnd();
// The StreamReader is automatically disposed of here.- Dynamic LINQ to SQL: Dynamic LINQ allows for flexible queries against databases, adapting as your application’s needs evolve.
using (var context = new DataContext())
{
var query = context.People.Where("City == @0 and Age > @1", "Seattle", 25);
foreach (var person in query)
{
Console.WriteLine(person.Name);
}
}By integrating these snippets into your daily coding process, you can not only improve the efficiency and clarity of your code, but also unlock the full potential of C# and .NET for creating powerful and scalable applications. These snippets act as a toolbox for exploring the vast world of .NET programming, ensuring that each line of code you produce reflects your dedication to quality and professionalism.
O Newtonsoft é uma biblioteca de serialização JSON para .NET, que permite converter objetos em JSON e vice-versa de maneira fácil e rápida. A serialização e a desserialização em JSON existem justamente para permitir que a aplicação entenda, interprete e manipule os dados que recebe e envia. Quando sistemas conversam entre si, eles não trocam objetos, classes, structs ou modelos internos; trocam texto estruturado, normalmente JSON.
Então o papel da serialização e da desserialização é transformar esse texto em algo que sua aplicação consegue usar, e transformar seus objetos internos em um formato que outros serviços consigam ler.
Quando você consome dados seja de uma API REST, de uma fila RabbitMQ, de um tópico Kafka, de um webhook do Pipefy ou de qualquer outra fonte — o que chega normalmente é uma string JSON. Essa string sozinha não serve para muita coisa, então a aplicação precisa convertê-la para um objeto fortemente tipado, como suas classes C#. Esse processo é a desserialização. É ela que pega o JSON e "dissolve" aquele texto em um objeto que você pode acessar normalmente, com propriedades e tipos corretos. Sem desserializar, sua aplicação não saberia interpretar nada: seria como receber um texto codificado sem ter a chave.
Do outro lado, quando você precisa publicar algo enviar uma mensagem pro RabbitMQ, chamar uma API externa, registrar um evento, mandar dados para um microserviço, você não pode enviar objetos diretamente, porque eles só existem dentro da memória e da linguagem de programação. Então você faz o inverso: pega seu objeto estruturado e o transforma em JSON. Esse processo é a serialização. Só depois desse processo o dado fica no formato padrão para ser enviado, armazenado ou trafegado.
Em outras palavras, a serialização e a desserialização são o “idioma comum” que faz sistemas diferentes conseguirem conversar. Sua aplicação pode ser .NET; outra pode ser Node.js; outra pode ser Python; outra pode ser escrita em Rust; outra pode ser um servidor em PHP. O JSON é o terreno neutro onde todos se entendem.
Isso garante interoperabilidade, compatibilidade e clareza. É por isso que quase todas as arquiteturas modernas APIs REST, mensageria, eventos, microservices dependem de JSON como formato universal. O JSON é leve, fácil de manipular, fácil de validar e muito flexível. E você só consegue fazer sua aplicação “entender” essa linguagem através da desserialização, e só consegue se comunicar com outros serviços fazendo a serialização.
É uma das bibliotecas mais populares para trabalhar com JSON em aplicações .NET, incluindo aplicativos desktop, web e móveis. A biblioteca fornece uma variedade de recursos, como:
- Serialização e desserialização de objetos em JSON;
- Suporte a diferentes tipos de dados, como primitivos, objetos complexos e coleções;
- Personalização da serialização e desserialização através de atributos e configurações;
- Suporte a serialização e desserialização assíncrona;
- Integração com frameworks .NET, como (link unavailable) e .NET Core.
dotnet add package NewtonsoftO JSON (JavaScript Object Notation) tornou-se um formato popular para troca de dados entre sistemas devido à sua simplicidade e facilidade de leitura tanto por humanos quanto por máquinas. No ecossistema C#, uma das maneiras mais comuns de trabalhar com JSON é através da biblioteca Newtonsoft.Json (também conhecida como Json.NET). Esta biblioteca é amplamente utilizada devido à sua performance, flexibilidade e facilidade de uso.
A Serialização é o processo de converter um objeto C# em uma string JSON. Isso é útil quando você deseja enviar dados de um aplicativo C# para outro sistema ou armazená-los em um formato que possa ser facilmente compartilhado ou persistido. Para serializar um objeto em JSON utilizando o Json.NET, você pode utilizar o método "JsonConvert.SerializeObject()" da seguinte maneira:
using Newtonsoft.Json;
// Definindo uma classe de exemplo
public class Pessoa
{
public string Nome { get; set; }
public int Idade { get; set; }
}
class Program
{
static void Main(string[] args)
{
// Criando uma instância da classe Pessoa
Pessoa pessoa = new Pessoa { Nome = "João", Idade = 30 };
// Serializando o objeto em JSON
string json = JsonConvert.SerializeObject(pessoa);
// Exibindo o JSON serializado
Console.WriteLine(json);
}
}A Desserialização é o processo de converter uma string JSON de volta para um objeto C#. Isso é útil quando você recebe dados em formato JSON e precisa trabalhar com eles dentro de seu aplicativo C#. Para desserializar JSON em um objeto C# utilizando o Json.NET, você pode utilizar o método "JsonConvert.DeserializeObject()" da seguinte maneira:
using Newtonsoft.Json;
class Program
{
static void Main(string[] args)
{
// JSON de exemplo
string json = "{\"Nome\":\"Maria\",\"Idade\":25}";
// Desserializando o JSON em um objeto Pessoa
Pessoa pessoa = JsonConvert.DeserializeObject<Pessoa>(json);
// Exibindo os dados do objeto desserializado
Console.WriteLine($"Nome: {pessoa.Nome}, Idade: {pessoa.Idade}");
}
}https://medium.com/codex/web-api-request-validation-e8650d71cf31
O ASP.NET lançado pela Microsoft em 2002 é uma estrutura de desenvolvimento web da Microsoft usada para criar aplicativos web dinâmicos e robustos. Faz parte da plataforma .NET e permite a criação de sites, serviços web e aplicações web. ASP.NET suporta várias abordagens e templates prontos de desenvolvimento para API REST, incluindo Web Forms, MVC (Model-View-Controller), Web API, Razor Pages e Minimal APIs.
Com o tempo percebeu-se forte acoplamento ao Windows e necessidade de maior flexibilidade e modernização. Rápido, modular e enxuto!
ASP.NET é uma plataforma poderosa e flexível para o desenvolvimento de aplicações web. Com suporte para várias abordagens e padrões, juntamente com uma forte integração com a plataforma .NET, oferece um ambiente robusto e produtivo para criar desde pequenos sites até aplicações web complexas e escaláveis.
Principais Características do ASP.NET Core: Suporte a DI integrado ao framework e elimina a necessidade de bibliotecas externas para injeção de dependências.
-
Desenvolvimento Baseado em Servidor: ASP.NET permite a execução de código no servidor, o que gera o HTML enviado ao cliente (navegador). Isso facilita a criação de páginas dinâmicas e interativas.
-
Componentes Reutilizáveis: Fornece uma vasta gama de componentes de UI e lógica de negócios que podem ser reutilizados em diferentes partes da aplicação.
-
Modelos de Desenvolvimento: Kestrel embutido na aplicação - não depender exclusivamente do IIS.
- Web Forms: Abordagem tradicional, similar ao desenvolvimento de aplicativos desktop, com componentes de arrastar e soltar.
- MVC (Model-View-Controller): Separação clara entre lógica de negócios, interface de usuário e controle de fluxo, facilitando o desenvolvimento e manutenção.
- Web API: Focado na criação de serviços HTTP que podem ser consumidos por diferentes clientes, como navegadores e dispositivos móveis.
- Razor Pages: Abordagem simples e baseada em páginas, ideal para páginas de UI que não exigem a complexidade do MVC.
-
Segurança Integrada: Suporte integrado para autenticação/autorização com Identity e proteção contra ataques comuns (como XSS e CSRF).
-
Performance e Escalabilidade: ASP.NET Core, a versão mais recente, é otimizada para alta performance e pode ser executada em múltiplas plataformas (Windows, Linux, macOS).
-
Ferramentas de Desenvolvimento: Excelente integração com o Visual Studio, oferecendo ferramentas poderosas de depuração, testes e implantação.
-
appsettings.jsonconfigurações de logging e host e variáveis de ambiente, substitui antigos arquivos XML, tornando a configuração mais intuitiva. -
Middleware pipeline: Arquitetura baseada em cadeia de middlewares configuráveis.
-
Suporte nativo ao SignalR (comunicação em tempo real).
-
Suporte a gRPC para comunicação entre microsserviços.
Criando um Scaffold de um novo Projeto ASP.NET na Linha de Comando:
dotnet new sln -o REST # solution
cd REST
dotnet new webapi -o REST # aplicação ASP.NET Minimal API
dotnet sln add ./REST/REST.csproj # diretório/solution
dotnet run --project REST
# Output: http://localhost:3753/weatherforecastExemplo de Aplicação ASP.NET: Aqui está um exemplo básico usando ASP.NET Core MVC para criar uma aplicação simples.
Passo 1: Criar um Novo Projeto ASP.NET Core MVC. No Visual Studio:
- Selecione
File > New > Project. - Escolha ASP.NET Core Web Application e clique em Next.
- Nomeie o projeto, selecione Web Application (Model-View-Controller) e clique em Create.
Passo 2: Estrutura de Diretórios
O projeto criado terá a seguinte estrutura:
- Controllers: Contém controladores que gerenciam a lógica da aplicação.
- Views: Contém as views (interfaces de usuário) que são renderizadas.
- Models: Contém modelos que representam dados da aplicação.
Passo 3: Criar um Controlador
Adicione um controlador chamado HomeController em Controllers/HomeController.cs:
using Microsoft.AspNetCore.Mvc;
public class HomeController : Controller
{
public IActionResult Index()
{
ViewData["Message"] = "Hello, ASP.NET Core!";
return View();
}
}Passo 4: Criar uma View
Adicione uma view chamada Index em Views/Home/Index.cshtml:
@{
ViewData["Title"] = "Home Page";
}
<h1>@ViewData["Message"]</h1>Passo 5: Executar a Aplicação
Pressione F5 ou clique em Run para executar a aplicação. O navegador deve exibir a mensagem "Hello, ASP.NET Core!".
Vantagens do ASP.NET:
-
Produtividade: Ferramentas e frameworks que aceleram o desenvolvimento.
-
Flexibilidade: Suporte para múltiplas arquiteturas e padrões de desenvolvimento.
-
Comunidade e Suporte: Grande comunidade de desenvolvedores e vasto número de recursos e bibliotecas disponíveis.
-
Desempenho: ASP.NET Core é conhecido por seu alto desempenho e capacidade de escalar em ambientes de produção.
Temos também o ASP.NET Core que é uma versão moderna, multiplataforma e de alto desempenho do ASP.NET, desenvolvida pela Microsoft. É uma reformulação completa do ASP.NET tradicional, projetada para ser leve, modular e eficiente, com o objetivo de atender às necessidades modernas de desenvolvimento de aplicações web.
ASP.NET Core representa uma evolução significativa em relação ao ASP.NET tradicional. Com sua modularidade, desempenho otimizado, e suporte multiplataforma, ASP.NET Core é a escolha recomendada para novos desenvolvimentos. ASP.NET tradicional ainda é relevante para manutenção de aplicações existentes, mas para novos projetos, ASP.NET Core oferece vantagens substanciais em termos de flexibilidade, performance e modernidade.
O ASP.NET e ASP.NET Core são ambas estruturas de desenvolvimento web da Microsoft, mas elas diferem significativamente em termos de arquitetura, capacidades e enfoque. Aqui estão as principais diferenças entre elas:
ASP.NET:
-
Plataforma: ASP.NET é construído sobre o .NET Framework e é projetado para funcionar apenas no ambiente Windows.
-
Desempenho: O ASP.NET tradicional é menos eficiente em termos de desempenho em comparação ao ASP.NET Core devido à sua arquitetura mais pesada e dependência do .NET Framework.
-
Modularidade: ASP.NET não é tão modular quanto o ASP.NET Core. Ele é uma estrutura monolítica, o que significa que você não pode escolher os componentes que deseja usar; você precisa levar todo o framework.
-
Tipos de Aplicações: ASP.NET suporta várias abordagens como Web Forms, MVC, e Web API, mas essas abordagens são separadas e têm diferentes padrões de programação.
-
Desenvolvimento de Aplicações: Mais adequado para aplicações que serão implantadas em servidores Windows. Tem forte integração com IIS (Internet Information Services).
-
Atualização e Suporte: O desenvolvimento e atualizações do ASP.NET tradicional têm sido mais lentos e limitados, pois a Microsoft está focando mais no ASP.NET Core para novos desenvolvimentos.
ASP.NET Core:
-
Plataforma: ASP.NET Core é multiplataforma, funcionando em Windows, Linux e macOS. Ele é construído sobre o .NET Core (ou mais recentemente, o .NET 5+).
-
Desempenho: ASP.NET Core é otimizado para alto desempenho e eficiência. Ele utiliza um pipeline de middleware leve e modular que melhora o desempenho geral.
-
Modularidade: Extremamente modular, permitindo que os desenvolvedores incluam apenas os componentes que são necessários para a aplicação. Isso reduz a sobrecarga e melhora o desempenho.
-
Tipos de Aplicações: ASP.NET Core unifica a abordagem para MVC, Web API, e Razor Pages, proporcionando uma experiência de desenvolvimento mais consistente.
-
Desenvolvimento de Aplicações: Melhor suporte para contêineres, como Docker, facilitando a criação e implantação de aplicativos em ambientes de nuvem e em vários sistemas operacionais.
-
Atualização e Suporte: A Microsoft está ativamente desenvolvendo e aprimorando o ASP.NET Core, tornando-o a principal plataforma para novos desenvolvimentos web. Recebe atualizações frequentes e novos recursos.
-
Injeção de Dependência: Suporte embutido para injeção de dependência (DI), permitindo a construção de aplicações mais testáveis e configuráveis.
-
Middleware: Utiliza middleware configurável e personalizável para compor o pipeline de processamento de solicitações, oferecendo maior controle sobre o comportamento do aplicativo.
Comparação Resumida:
| Característica | ASP.NET | ASP.NET Core |
|---|---|---|
| Plataforma | Windows | Multiplataforma (Windows, Linux, macOS) |
| Desempenho | Menos eficiente | Altamente otimizado |
| Modularidade | Monolítico | Altamente modular |
| Tipos de Aplicações | Web Forms, MVC, Web API separados | Unificação de MVC, Web API, Razor Pages |
| Suporte para Contêineres | Limitado | Suporte nativo para Docker |
| Atualizações | Mais lentas | Atualizações frequentes |
| Injeção de Dependência | Não embutido | Embutido |
| Middleware | Não configurável | Configurável |
O IIS Express é um web server (servidor web) para executar o código ASP.NET Framework na web, através da sua máquina local. IIS Express é um servidor web que foi projetado principalmente para facilitar o desenvolvimento e testes de aplicações web em um ambiente de desenvolvimento local. Ele oferece muitas das mesmas funcionalidades que o Internet Information Services (IIS) completo, mas com algumas diferenças importantes que o tornam mais adequado para desenvolvimento em vez de produção.
IIS Express é uma excelente ferramenta para desenvolvimento e teste de aplicações web, oferecendo uma experiência leve e fácil de usar para desenvolvedores. No entanto, para implantações em ambientes de produção, o IIS completo é a escolha apropriada, devido ao seu desempenho superior, robustez em termos de segurança e ferramentas avançadas de gerenciamento e monitoramento.
Características do IIS Express:
-
Facilidade de Uso:
- Instalação Simplificada: Não requer permissões de administrador para instalação e configuração.
- Integrado ao Visual Studio: Funciona perfeitamente com o Visual Studio, facilitando o desenvolvimento e a depuração de aplicações web diretamente dentro do ambiente de desenvolvimento.
-
Funcionalidades de IIS:
- Compatibilidade: Suporta muitas das funcionalidades do IIS completo, como suporte a ASP.NET, autenticação, e extensões.
- Configuração Similar: Usa arquivos de configuração semelhantes aos do IIS, permitindo uma fácil transição do desenvolvimento para o servidor de produção.
-
Ambiente de Desenvolvimento:
- Focado no Desenvolvimento Local: Otimizado para rodar localmente em um ambiente de desenvolvimento, proporcionando uma experiência leve e rápida para desenvolvedores.
- Portabilidade: Facilita a configuração de ambientes de desenvolvimento em diferentes máquinas sem a complexidade de configurar um servidor completo.
Limitações do IIS Express para Produção:
-
Desempenho e Escalabilidade:
- Desempenho Limitado: Não é projetado para lidar com grandes volumes de tráfego ou altas cargas de trabalho como o IIS completo.
- Recursos Limitados: Não possui todas as otimizações de desempenho que o IIS completo oferece para ambientes de produção.
-
Segurança: Segurança Restrita: Embora suporte autenticação e outras funcionalidades de segurança, não é tão robusto quanto o IIS completo para ambientes de produção, que exigem níveis mais altos de segurança e controle.
-
Gestão e Monitoramento:
- Ferramentas Limitadas: Faltam algumas das ferramentas avançadas de gerenciamento, monitoramento e diagnóstico que estão disponíveis no IIS completo.
Uso Adequado de IIS Express:
Desenvolvimento e Teste Local:
- Ideal para desenvolvimento local de aplicações web.
- Facilita a depuração e o teste de funcionalidades antes da implantação em um servidor de produção.
Transição para Produção:
-
IIS Completo: Para ambientes de produção, é recomendado usar o IIS completo, que oferece melhor desempenho, segurança aprimorada, e ferramentas de gerenciamento avançadas.
-
Configuração Semelhante: A transição do IIS Express para o IIS completo é facilitada pela similaridade nas configurações e suporte a funcionalidades.
Razor Pages é uma abordagem de desenvolvimento de aplicações web introduzida no ASP.NET Core, que facilita a criação de interfaces de usuário dinâmicas. Ao contrário do modelo MVC (Model-View-Controller), Razor Pages foca em um design orientado a páginas, simplificando o desenvolvimento de páginas da web e mantendo o código mais coeso e intuitivo.
Razor Pages é uma abordagem moderna e eficiente para o desenvolvimento de páginas da web no ASP.NET Core, especialmente útil para aplicações que se beneficiam de uma estrutura orientada a páginas mais simples e direta. Ele combina a flexibilidade da sintaxe Razor com a organização modular de modelos de página, facilitando o desenvolvimento e a manutenção de aplicações web dinâmicas.
Características Principais do Razor Pages:
-
Abordagem Baseada em Páginas: Cada página Razor é composta por um arquivo
.cshtml(para a marcação HTML e o código Razor) e um arquivo de modelo de página associado (PageModel, geralmente com extensão.cshtml.cs). -
Sintaxe Razor: Usa a sintaxe Razor, que permite a combinação de código C# com HTML de maneira elegante e fluida.
-
Estrutura de Arquivos: Os arquivos
.cshtmle seus modelos de página correspondentes são armazenados na pastaPagespor padrão. -
Binding de Dados e Manipulação: Permite a vinculação de dados diretamente no arquivo de modelo de página (
PageModel), facilitando a manipulação de dados e lógica de negócios. -
Handlers: Em vez de controladores MVC, Razor Pages usa "handlers" (como
OnGet,OnPost, etc.) para lidar com solicitações HTTP, proporcionando uma maneira mais direta de mapear ações às solicitações. -
Encapsulamento de Lógica: A lógica da página é encapsulada no modelo de página, o que promove uma organização mais clara e modular do código.
Exemplo Básico de Razor Page: Aqui está um exemplo simples de uma Razor Page que exibe uma mensagem de boas-vindas.
Arquivo Index.cshtml:
@page
@model IndexModel
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Welcome</title>
</head>
<body>
<h1>@Model.Message</h1>
</body>
</html>Arquivo Index.cshtml.cs:
using Microsoft.AspNetCore.Mvc.RazorPages;
public class IndexModel : PageModel
{
public string Message { get; private set; }
public void OnGet()
{
Message = "Welcome to Razor Pages!";
}
}Neste exemplo:
- O arquivo
Index.cshtmlcontém a marcação HTML e o código Razor que exibe a mensagem. - O arquivo
Index.cshtml.csé o modelo de página que contém a lógica para a página, onde a mensagem "Welcome to Razor Pages!" é definida no métodoOnGet.
Vantagens do Razor Pages:
-
Simplicidade e Intuitividade: Menos arquivos e uma estrutura mais simples em comparação ao padrão MVC, tornando-o ideal para páginas da web que não necessitam de uma arquitetura complexa.
-
Desempenho: Melhor desempenho devido à menor complexidade e sobrecarga.
-
Produtividade: Mais rápido para desenvolver páginas simples, pois a lógica e a apresentação estão mais próximas e coesas.
O Entity Framework (EF) é uma biblioteca de mapeamento objeto-relacional (ORM) desenvolvida pela Microsoft para a plataforma .NET. Ele permite que os desenvolvedores trabalhem com dados relacionais usando objetos .NET, eliminando a necessidade de escrever código SQL diretamente.
O Entity Framework facilita o desenvolvimento de aplicações de dados, automatizando muitas tarefas comuns associadas ao acesso a bancos de dados. Entity Framework é uma poderosa ferramenta ORM para desenvolvedores .NET, simplificando o acesso e manipulação de dados em aplicações.
Com suporte a múltiplos modelos de desenvolvimento, consultas LINQ e migrações, ele melhora a produtividade e manutenibilidade dos aplicativos, embora possa ter algumas limitações de desempenho e flexibilidade em comparação com o acesso direto ao SQL.
Principais Características do Entity Framework:
-
Mapeamento Objeto-Relacional (ORM): Transforma dados armazenados em um banco de dados relacional em objetos .NET e vice-versa. Isso permite que os desenvolvedores trabalhem com dados usando paradigmas de programação orientada a objetos.
-
Modelos de Desenvolvimento:
- Code First: Permite que os desenvolvedores definam o modelo de dados usando classes C# ou VB.NET. O EF cria o esquema do banco de dados com base nessas classes.
- Database First: Começa com um banco de dados existente e gera classes de entidade com base no esquema do banco de dados.
- Model First: Permite que os desenvolvedores definam um modelo usando um designer visual, que então gera o esquema do banco de dados e as classes de entidade.
-
Consultas LINQ: Suporte para Language Integrated Query (LINQ), que permite escrever consultas de dados em C# ou VB.NET. O EF converte essas consultas em SQL e as executa no banco de dados.
-
Migrações: Gerenciamento de mudanças no esquema do banco de dados através de migrações. Isso facilita a evolução do esquema de banco de dados de forma controlada.
-
Lazy Loading e Eager Loading:
- Lazy Loading: Carrega dados relacionados sob demanda quando eles são acessados pela primeira vez.
- Eager Loading: Carrega dados relacionados junto com a consulta inicial, evitando múltiplas consultas ao banco de dados.
-
Validação: Suporte a validações de dados usando atributos de anotação de dados (Data Annotations) e a API de validação.
Exemplo Básico de Uso do Entity Framework:
Passo 1: Configurar o Projeto
- Crie um novo projeto no Visual Studio.
- Instale o pacote NuGet
Microsoft.EntityFrameworkCoreeMicrosoft.EntityFrameworkCore.SqlServer(ou outro provedor de banco de dados).
Passo 2: Definir o Modelo de Dados
public class Product
{
public int ProductId { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
}Passo 3: Criar o Contexto do Banco de Dados
using Microsoft.EntityFrameworkCore;
public class AppDbContext : DbContext
{
public DbSet<Product> Products { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("YourConnectionStringHere");
}
}Usar o Contexto para Acessar Dados
class Program
{
static void Main(string[] args)
{
using (var context = new AppDbContext())
{
// Adicionar um novo produto
var product = new Product { Name = "Example Product", Price = 9.99M };
context.Products.Add(product);
context.SaveChanges();
// Consultar produtos
var products = context.Products.ToList();
foreach (var p in products)
{
Console.WriteLine($"{p.ProductId}: {p.Name} - {p.Price}");
}
}
}
}Vantagens do Entity Framework:
-
Produtividade: Reduz a quantidade de código necessário para acessar e manipular dados, permitindo que os desenvolvedores se concentrem mais na lógica de negócios.
-
Manutenibilidade: Facilita a manutenção e a evolução do esquema de banco de dados e do código de acesso a dados.
-
Abstração de Banco de Dados: Permite trocar facilmente de fornecedor de banco de dados sem mudar o código de acesso a dados.
-
Validação e Segurança: Integração com recursos de validação de dados e segurança, reduzindo o risco de erros e vulnerabilidades.
Limitações do Entity Framework:
-
Desempenho: Pode ser mais lento em comparação ao uso direto de SQL, especialmente para consultas complexas.
-
Complexidade: A curva de aprendizado pode ser íngreme para desenvolvedores que não estão familiarizados com ORM.
-
Flexibilidade: Pode ser menos flexível para certos tipos de consultas ou operações avançadas de banco de dados.
Dapper é uma biblioteca de acesso a dados para .NET classificada como um micro-ORM. Ele não tenta abstrair o banco de dados de forma completa como um ORM tradicional; a ideia central do Dapper é dar a você controle explícito do SQL, adicionando apenas o mínimo necessário para mapear resultados de consultas para objetos C# de forma rápida, segura e eficiente.
Em resumo, Dapper é uma ferramenta para quem quer o poder do SQL puro, com o conforto do mapeamento automático, sem abrir mão de desempenho nem assumir o peso conceitual de um ORM completo.
Na prática, o Dapper funciona como uma camada muito fina sobre o ADO.NET. Você continua escrevendo SQL “na mão”, define exatamente quais colunas quer buscar, quais joins usar e como filtrar os dados, mas não precisa lidar com o trabalho repetitivo de abrir leitores, iterar linhas e atribuir valores manualmente às propriedades dos objetos. O Dapper faz esse mapeamento automaticamente, usando convenções simples (nomes de colunas ↔ propriedades), com custo de performance muito baixo.
Ele é chamado de micro-ORM porque resolve apenas o problema do mapeamento objeto-relacional. Diferente de ORMs completos como Entity Framework, ele não faz rastreamento de entidades, não gera SQL automaticamente, não controla estado de objetos, não implementa Unit of Work nem oferece migrações de banco. Tudo isso é deliberado: o foco do Dapper é ser previsível, rápido e transparente. Você sempre sabe exatamente qual SQL está sendo executado.
O uso típico do Dapper envolve trabalhar com uma IDbConnection, executar comandos como Query, QuerySingle, Execute e receber de volta objetos fortemente tipados, listas ou valores escalares. Ele suporta parâmetros de forma segura, evitando SQL injection, lida bem com múltiplos resultados, mapeamento de relações simples e integra-se naturalmente a qualquer framework .NET, como ASP.NET Core, Minimal APIs, serviços em background ou aplicações de console.
O principal motivo para escolher Dapper é performance aliada a controle. Ele é amplamente utilizado em sistemas de alta carga, APIs que precisam de latência baixa, serviços financeiros, pipelines de dados e cenários onde o desenvolvedor quer evitar a “mágica” de ORMs mais pesados. Em contrapartida, ele exige mais disciplina: como o SQL é explícito, a responsabilidade pelo design das consultas e pela consistência do domínio fica mais nas mãos de quem desenvolve.
Dapper não é um micro-framework back-end, nem algo comparável ao Lumen. Dapper é exclusivamente um micro-ORM. Ele não fornece servidor HTTP, roteamento, middleware, injeção de dependência, ciclo de requisição, configuração de aplicação ou qualquer estrutura de aplicação. Ele apenas mapeia resultados de SQL para objetos .NET de forma extremamente leve e performática. Em termos práticos, Dapper é uma biblioteca de acesso a dados, não um framework.
Lumen, por outro lado, é um micro-framework web. Ele cuida de todo o pipeline de uma aplicação back-end: requisições HTTP, rotas, controllers, middleware, configuração, DI, logging, etc. O fato de o Lumen usar o Eloquent (ORM do Laravel) não o transforma em um “micro-ORM”; o ORM é apenas um componente dentro de um framework maior.
A analogia correta seria mais ou menos assim: Lumen está para Laravel como ASP.NET Core Minimal APIs estão para ASP.NET Core MVC. Já Dapper estaria no mesmo “nível” de abstração que o Eloquent, o Doctrine ou o Hibernate — todos são ORMs (ou micro-ORMs), não frameworks.
Se você quiser alinhar conceitos de forma precisa:
- Dapper ≈ Eloquent (sem Active Record) ≈ Doctrine DBAL (parte)
- Lumen ≈ ASP.NET Core (Minimal / API-only) ≈ Fastify / Express
Ou seja, Dapper pode ser usado dentro de um framework (ASP.NET Core, Nancy, ServiceStack, Minimal APIs etc.), assim como o Eloquent é usado dentro do Laravel ou Lumen, mas ele não substitui o framework. Ele não “contém” um back-end; ele apenas resolve o problema específico de acesso a dados com SQL explícito e mapeamento leve.
Resumindo em uma frase bem direta: Lumen é um micro-framework que usa um ORM; Dapper é apenas um micro-ORM e precisa de um framework ao redor.
Vamos fazer a consulta de dados via API GraphQL do Pipefy com o .NET e exibir esses dados no CLI de console do terminal no formato JSON. Para isso, siga os passos abaixo:
-
Token de autenticação do Pipefy: https://app.pipefy.com/tokens
-
Roles de permissão do usuário Pipefy: Admin
-
API do Pipefy: https://api.pipefy.com/graphql
Exemplo padrão de consulta GraphQL via teste do Postman:
query {
card(id: [card]) {
title
done
id
fields {
date_value
datetime_value
filled_at
float_value
indexName
name
native_value
report_value
updated_at
value
}
updated_at
}
}
Vamos representar o mesmo com o nosso código do .NET abaixo:
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using System.Text.Json;
class Program
{
static async Task Main(string[] args)
{
// Autenticação da API do Pipefy
var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "[api token pipefy]");
// Request da API do Pipefy
var query = "{\"query\": \"{ card(id: 1006982319) { title, done, id, fields { date_value, datetime_value, filled_at, float_value, indexName, name, native_value, report_value, updated_at, value }, updated_at } }\"}";
var content = new StringContent(query, System.Text.Encoding.UTF8, "application/json");
// Response da API do Pipefy
var response = await client.PostAsync("https://api.pipefy.com/graphql", content);
var responseString = await response.Content.ReadAsStringAsync();
// Exibe a resposta recebida
Console.WriteLine("Resposta recebida:");
Console.WriteLine(responseString);
if (response.IsSuccessStatusCode)
{
// Verifica se a resposta não está vazia antes de tentar desserializar
if (!string.IsNullOrEmpty(responseString))
{
try
{
// Desserializa a string JSON
var jsonData = JsonSerializer.Deserialize<JsonElement>(responseString);
// Acessa e exibe o título do card
var title = jsonData.GetProperty("data").GetProperty("card").GetProperty("title").GetString();
Console.WriteLine("Título do card: " + title);
}
catch (JsonException ex)
{
Console.WriteLine("Erro ao desserializar o JSON: " + ex.Message);
}
}
else
{
Console.WriteLine("A resposta está vazia.");
}
}
else
{
Console.WriteLine("Erro na requisição. Código de status: " + response.StatusCode);
}
}
}
O Ocelot é uma biblioteca de código aberto para construção de API gateways em .NET. Ele foi projetado para simplificar o processo de criação de gateways que atuam como intermediários entre clientes e várias APIs de serviços nos bastidores. Esses gateways podem ser úteis em cenários de microserviços, onde várias APIs precisam ser acessadas por meio de uma única interface. O Ocelot é uma ferramenta útil para construir gateways de API em .NET, simplificando o processo de roteamento, autenticação, autorização e transformação de solicitações e respostas.
Com sua simplicidade de configuração, flexibilidade e suporte a padrões de segurança, o Ocelot é uma escolha popular para desenvolvedores que precisam criar gateways de API eficientes e escaláveis em suas aplicações .NET.
O Ocelot é um API Gateway para plataforma .NET. Este projeto destina-se a pessoas que usam o .NET Core executando uma arquitetura orientada a microserviços / serviços que precisam de um ponto de entrada unificado em seu sistema. No entanto, ele funcionará com qualquer coisa que fale HTTP e seja executado em qualquer plataforma suportada pelo ASP.NET Core.
Principais Características do Ocelot:
-
Gateway de API: Permite que os desenvolvedores criem um ponto de entrada único para acessar várias APIs de serviço.
-
Roteamento de Requisições: Roteia as solicitações do cliente para as APIs de serviço correspondentes com base em critérios como URL, método HTTP, cabeçalhos etc.
-
Autenticação e Autorização: Oferece suporte para autenticação e autorização, permitindo controlar o acesso às APIs de serviço com base em políticas de segurança.
-
Transformação de Requisições e Respostas: Permite transformar solicitações e respostas entre o formato do cliente e o formato esperado pela API de serviço.
-
Cache de Respostas: Oferece suporte para cache de respostas para melhorar o desempenho e reduzir a carga nos serviços de backend.
-
Logging e Monitoramento: Possibilita o registro de solicitações, respostas e eventos para monitoramento e análise.
-
Extensibilidade: É altamente extensível e pode ser personalizado com middleware e plugins para atender às necessidades específicas do projeto.
Exemplo de Configuração do Ocelot:
Aqui está um exemplo básico de configuração do Ocelot em um arquivo ocelot.json:
{
"Routes": [
{
"DownstreamPathTemplate": "/api/{everything}",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 5001
}
],
"UpstreamPathTemplate": "/{everything}",
"UpstreamHttpMethod": [ "Get" ]
}
]
}Neste exemplo, todas as solicitações recebidas em /api/{everything} serão roteadas para http://localhost:5001/{everything}.
Vantagens do Ocelot:
-
Simplicidade de Configuração: Fácil de configurar e usar, reduzindo a complexidade na construção de gateways de API.
-
Flexibilidade: Oferece flexibilidade para rotear, autenticar, autorizar e transformar solicitações e respostas conforme necessário.
-
Padrões de Segurança: Suporta padrões de segurança como OAuth, JWT e OpenID Connect para autenticação e autorização.
-
Desempenho: Pode melhorar o desempenho ao cache de respostas e otimização de solicitações, reduzindo o tempo de resposta.
-
Comunidade Ativa: Tem uma comunidade ativa de desenvolvedores que contribuem com melhorias, correções de bugs e suporte.
Microsserviços do .Net Core usando arquitetura limpa: Guia completo para criar aplicativos de edição empresarial de ponta a ponta.
Os microsserviços são um padrão de design no qual os aplicativos são compostos de módulos independentes que se comunicam entre si dentro de limites bem definidos. Isso facilita o desenvolvimento, o teste e a implantação de partes isoladas do seu aplicativo.
Bem-vindo ao "Criando microsserviços .Net Core usando arquitetura limpa", o curso definitivo projetado para desenvolvedores ansiosos para dominar a arte de criar microsserviços escaláveis, eficientes e robustos utilizando a plataforma .Net Core, em conjunto com uma variedade de ferramentas e tecnologias essenciais. Essa jornada de aprendizado abrangente abrange Docker, Kubernetes, Identity Server 4, Rabbit MQ, Angular 15, GRPC, Istio Service Mesh, SQL Server, MongoDB, PostgreSQL, Redis, Ocelot, Nginx, Azure, Helm Charts e Auto Scaling. Abaixo, mencionei a versão mais recente do código que é feita usando .Net 8 e Angular 18.
Você mergulhará em exercícios práticos, ganhando uma experiência inestimável na implantação e supervisão de seus microsserviços usando Docker e Kubernetes. Descubra como incorporar perfeitamente o Identity Server 4 para autenticação e autorização fortificadas, aproveitar o Rabbit MQ para mensagens simplificadas e aproveitar o GRPC para permitir uma comunicação eficiente entre seus microsserviços.
Além disso, aprofunde-se nas complexidades do Istio Service Mesh para gerenciar habilmente o tráfego de microsserviços. Descubra os segredos da configuração e otimização do SQL Server, MongoDB, PostGreSQL e Redis para se adequar impecavelmente à sua arquitetura de microsserviços. Além disso, você usará o poder do Ocelot e do Nginx para supervisionar seu gateway de API de microsserviços enquanto orquestra implantações no Azure com precisão usando gráficos do Helm.
Embarque em sua jornada rumo ao domínio dos microsserviços com nosso curso abrangente, cuidadosamente elaborado para equipá-lo com as habilidades e conhecimentos necessários para se destacar neste campo dinâmico.
Nesta seção, você adquirirá a experiência para construir um aplicativo de comércio eletrônico robusto usando um kit de ferramentas abrangente, incluindo asp.net core, Docker, Kubernetes, Helm Charts, Service Mesh e Angular 15. Aqui estão os insights essenciais que você obterá com este projeto:
-
Domínio da criação de um aplicativo de comércio eletrônico completo: você ganhará a proficiência para criar um aplicativo de comércio eletrônico completo e funcional, equipando-o com habilidades valiosas para projetos do mundo real.
-
Referência para projetos empresariais profissionais: Este projeto serve como uma referência inestimável para indivíduos que desejam aprender e desenvolver soluções corporativas de nível profissional. Oferece uma riqueza de conhecimentos e exemplos práticos.
-
Ênfase na excelência da implementação: Você não apenas descobrirá como implementar todas as camadas do aplicativo de forma eficaz, mas também seguirá as melhores práticas do setor em todo o projeto. Isso garante que seu trabalho esteja alinhado com os mais altos padrões observados no campo.
Aqui, você aprenderá uma variedade de tecnologias como:
- Arquitetura limpa
- .Net Core
- Estivador
- Kubernetes
- Azul
- Microsserviços
- Malha de serviço
- Angular
- Pilha ELK
- Padrão Pub/Sub
- GRPC
- Padrão de repositório
- Padrão de unidade de trabalho
- Padrão de especificação
- Gráficos do Helm
Como o Projeto está estruturado:
| A estrutura do back-end | A estrutura do cliente | Implantações |
![]() |
![]() |
![]() |
Warning
Disclaimer! Aviso e isenção de responsabilidade: Todos os esforços aplicados para tornar este projeto completo e preciso para o tópico, mas nenhuma garantia está implícita. Qualquer implementação neste projeto é MINHA e também emprestada do segmento de melhores práticas. TODO o conteúdo apresentado no estado em que se encontra, apenas para fins de aprendizagem. Além disso, este curso será atualizado à medida que uma estrutura nova e estável for lançada.
Instalação: Siga estas etapas para configurar seu ambiente de desenvolvimento: (Antes de Executar, Inicie a Área de Trabalho do Docker)
- Clonar o repositório
- Depois que o Docker for Desktop estiver instalado, vá para a opção Configurações > Avançado, no ícone do Docker na bandeja do sistema, para configurar a quantidade mínima de memória e CPU da seguinte forma:
- Memória: 7 GB
- CPU: 5
- No diretório raiz que inclui
docker-compose.ymlarquivos, execute o comando abaixo:
docker-compose -f docker-compose.yml -f docker-compose.override.yml up -d
Aqui está o fluxo de trabalho do aplicativo e as exibições da tecnologia usada nesta jornada.
Padrão Pub/Sub: No diagrama abaixo, como podemos ver antes do checkout, o evento criado é excluído do banco de dados Redis.
Gerenciamento de contêineres via Portainer:
Elasticsearch:
ACR Workloads:
AKS Workloads:
Pods Overview Kube Lens:
Deployment:
Replicasets:
ConfigMaps:
Secrets:
HPA (Horizontal Pods AutoScaler):
Istio enabled:
kubectl apply -f istio-init.yaml kubectl apply -f istio-minikube.yaml kubectl apply -f kiali-secret.yaml
Istio via Kubelens
Kiali (Gerenciamento de malha de serviço para Istio): Podemos encaminhar para a frente o mesmo usando lentes. Isso trará Kiali UI como
Carga de trabalho do catálogo Kiali
Visão geral do serviço Kiali
Visualização do Grafana
O Dapr - Distributed Application Runtime, é um runtime de código aberto criado para simplificar o desenvolvimento de aplicações distribuídas, principalmente microserviços, e ele se integra de maneira muito natural com o .NET, incluindo ASP.NET Core.
A ideia do Dapr é abstrair uma série de desafios comuns no desenvolvimento de sistemas distribuídos, como comunicação entre serviços, gerenciamento de estado, mensageria, pub/sub, bindings com serviços externos, observabilidade e até invocação segura de outros serviços, para que o desenvolvedor não precise reescrever soluções para esses problemas a cada projeto. Ele é construído em cima de conceitos modernos de nuvem, mas pode ser executado tanto localmente quanto em ambientes on-premises, edge ou em qualquer provedor cloud.
No contexto do .NET, o Dapr funciona como uma camada complementar ao seu código, rodando em sidecar (um processo separado que roda ao lado da sua aplicação). Esse sidecar expõe APIs HTTP ou gRPC para que a aplicação consuma funcionalidades distribuídas sem se preocupar com a implementação por baixo. Por exemplo, em vez de o desenvolvedor escrever código específico para gravar e recuperar estado de um banco NoSQL, ele pode chamar a API de estado do Dapr, e por trás disso o Dapr cuida de falar com o banco configurado. Isso torna sua aplicação desacoplada da tecnologia de persistência, permitindo trocar de provedor com mudanças mínimas. Outro cenário muito comum é a comunicação entre serviços, onde você pode invocar outro microserviço chamando a API do Dapr pelo nome do serviço, e o Dapr resolve a descoberta, roteamento e segurança dessa chamada.
No ecossistema .NET, a integração é bem fluida. Existe um SDK oficial do Dapr para .NET, que facilita ainda mais esse consumo. Ele provê classes, middlewares e extensões para ASP.NET Core que permitem, por exemplo, lidar com eventos pub/sub usando decorators em controllers, consumir estado como se fosse um repositório e registrar bindings para interações com serviços externos, tudo seguindo as convenções do .NET. Essa abordagem reduz a complexidade do código, mantém o foco nas regras de negócio e ainda oferece benefícios como resiliência, retries, circuit breakers e telemetria integrados.
O uso do Dapr se encaixa bem em cenários onde a aplicação .NET precisa crescer de forma modular, integrando-se com múltiplos serviços e plataformas, ou onde você quer que sua solução esteja preparada para rodar em arquiteturas distribuídas sem ficar preso a uma infraestrutura específica. É uma alternativa moderna que se compara a ferramentas de service mesh ou frameworks de microserviços, mas com foco em simplificar a vida do desenvolvedor e reduzir o acoplamento de tecnologias.
SignalR é uma biblioteca da Microsoft para .NET que permite comunicação em tempo real entre servidores e aplicações cliente, como páginas web, aplicativos mobile ou desktops. Em vez de o cliente ficar perguntando repetidamente ao servidor se há algo novo o famoso polling, que é caro, lento e ineficiente, o SignalR cria um canal de comunicação persistente onde servidor e cliente podem enviar mensagens um ao outro assim que elas acontecem. Isso transforma a aplicação em algo dinâmico, instantâneo e interativo, como se fosse uma conversa contínua.
O ponto mais importante é que o SignalR abstrai toda a complexidade de protocolos de comunicação. Em cenários modernos, ele tenta utilizar WebSockets primeiro, porque é o protocolo mais eficiente, mas caso o ambiente não suporte, ele recua automaticamente para outras tecnologias como Server-Sent Events ou Long Polling. Esse fallback é transparente, você não precisa reescrever nada; o SignalR escolhe a melhor opção disponível para garantir que a comunicação em tempo real funcione em qualquer lugar.
Ele é amplamente utilizado em situações onde o usuário precisa ver atualizações instantâneas sem recarregar a página. Por exemplo, chats online, notificações em dashboards, sistemas de monitoramento, atualizações de status de pedidos, sinais de telemetria, jogos multiplayer, rastreamento de veículos, integração com mensagens de fila e até sincronização colaborativa de documentos.
No ASP.NET Core, ele se integra naturalmente com todo o pipeline da aplicação, permitindo criar hubs, pontos centrais de comunicação, onde o servidor recebe mensagens e retransmite para grupos específicos de usuários ou para todos conectados.
O modelo mental é que você cria um “hub” no servidor, conecta o cliente a ele e depois ambos podem trocar mensagens nomeadas. É como se fossem métodos remotos: você chama do cliente um método do servidor e vice-versa. Isso elimina muita complexidade de sockets tradicionais e reduz todo o trabalho de infraestrutura para apenas escrever lógica de aplicação.
Na prática, o SignalR tornou o desenvolvimento de aplicações em tempo real muito mais acessível para quem trabalha no ecossistema .NET, porque você não precisa montar manualmente WebSockets, gerenciar conexões, lidar com reconexões ou manter compatibilidade entre navegadores. Ele fornece tudo pronto, inclusive gerando automaticamente IDs de conexão, grupos de broadcast e reconexão automática quando a rede cai.
O IronOCR é uma biblioteca .NET que fornece funcionalidades avançadas de reconhecimento óptico de caracteres (OCR). Ele permite que os desenvolvedores adicionem capacidades de OCR a suas aplicações .NET de forma simples e eficiente, permitindo a extração de texto de imagens e documentos digitalizados.
O IronOCR é uma biblioteca .NET poderosa e fácil de usar para reconhecimento óptico de caracteres (OCR). Com sua capacidade de extrair texto de imagens e documentos digitalizados, alta precisão e suporte para vários idiomas, o IronOCR é uma escolha popular para desenvolvedores que precisam integrar funcionalidades de OCR em suas aplicações .NET.
Principais Características do IronOCR:
-
Reconhecimento de Texto em Imagens: Capacidade de extrair texto de imagens digitais, incluindo formatos como JPEG, PNG, BMP e TIFF.
-
Suporte a Documentos Digitalizados: Reconhecimento de texto em documentos digitalizados, como PDFs, usando OCR para converter o conteúdo do documento em texto pesquisável e editável.
-
Suporte Multilíngue: Reconhece texto em várias línguas e caracteres especiais, facilitando o processamento de documentos em diferentes idiomas.
-
Processamento de Alta Qualidade: Oferece algoritmos avançados para garantir alta precisão no reconhecimento de texto, mesmo em documentos com baixa qualidade de imagem ou distorções.
-
API Fácil de Usar: API simples e intuitiva que permite aos desenvolvedores integrar facilmente funcionalidades de OCR em suas aplicações .NET.
-
Configurações Avançadas: Opções para configurar o comportamento do OCR, como idioma, resolução de imagem e algoritmos de reconhecimento.
-
Suporte para .NET Core e .NET Framework: Compatibilidade com ambas as plataformas .NET, permitindo que desenvolvedores usem o IronOCR em uma ampla gama de projetos.
-
Licença de Uso Flexível: Disponível em diferentes planos de licenciamento para atender às necessidades de desenvolvedores individuais, equipes e empresas.
Exemplo de Uso do IronOCR: Aqui está um exemplo simples de como usar o IronOCR para reconhecer texto em uma imagem:
using IronOcr;
class Program
{
static void Main(string[] args)
{
// Carregar imagem
var image = IronOcr.ImageToTextRenderer.LoadImageFromFile("image.png");
// Criar um objeto IronOCR
var ocr = new IronTesseract();
// Realizar OCR na imagem
var result = ocr.Read(image);
// Exibir o texto extraído
Console.WriteLine(result.Text);
}
}Vantagens do IronOCR:
-
Facilidade de Uso: API simples e intuitiva, facilitando a adição de funcionalidades de OCR em aplicações .NET.
-
Alta Precisão: Utiliza algoritmos avançados para garantir alta precisão no reconhecimento de texto, mesmo em condições desafiadoras.
-
Suporte Multilíngue: Reconhece texto em uma ampla variedade de idiomas e caracteres especiais.
-
Suporte para Diversos Formatos de Imagem: Capacidade de trabalhar com uma variedade de formatos de imagem, incluindo JPEG, PNG, BMP, TIFF e PDF.
-
Compatibilidade com .NET Core e .NET Framework: Pode ser utilizado em projetos .NET Core e .NET Framework, oferecendo flexibilidade para desenvolvedores.
-
Documentação Abundante: Disponibilidade de documentação detalhada, exemplos de código e suporte técnico para ajudar os desenvolvedores a começar rapidamente.
No mundo acelerado do desenvolvimento de software de hoje, é fundamental conhecer padrões de design que possam ajudar a criar código robusto, eficiente e sustentável. Um dos frameworks de programação mais amplamente utilizados para aplicações empresariais é o framework .NET. Vamos explorar os padrões de design mais comumente usados no desenvolvimento de .NET e como eles podem ser aplicados para resolver problemas comuns encontrados no desenvolvimento de software.
Ao incorporar esses padrões no seu código, você pode escrever um software de alta qualidade que é fácil de manter, estender e modificar ao longo do tempo. Entender e usar padrões de design no seu desenvolvimento .NET pode melhorar muito a qualidade, escalabilidade e manutenibilidade do seu código.
Antes de mergulharmos nos padrões de design mais usados no desenvolvimento .NET, vamos primeiro entender o que são padrões de design. Padrões de design são um conjunto de melhores práticas e soluções para problemas comuns que desenvolvedores de software enfrentam durante o processo de desenvolvimento. Esses padrões geralmente são reutilizáveis e podem ser aplicados a diferentes projetos.
Padrões de design não são um recurso de linguagem ou uma biblioteca, mas sim uma forma de organizar o código para torná-lo mais sustentável, extensível e reutilizável. Eles geralmente são categorizados em três tipos: padrões criacionais, padrões estruturais e padrões comportamentais.
Padrões criacionais lidam com mecanismos de criação de objetos, tentando criar objetos de maneira adequada à situação. Padrões estruturais lidam com a composição dos objetos, e padrões comportamentais lidam com a comunicação entre objetos. Padrões de design criacional são usados para criar objetos de uma forma adequada a uma situação específica. Os padrões de design criacional mais comumente usados no desenvolvimento do .NET são:
- Padrão Singleton: O padrão Singleton é usado para garantir que uma classe tenha apenas uma instância, e fornece um ponto global de acesso a essa instância. No .NET, o padrão Singleton é implementado usando um construtor privado e um campo estático que contém a única instância da classe. Esse padrão é útil quando você quer garantir que apenas uma instância de uma classe seja criada, e deseja fornecer um ponto global de acesso a essa instância.
public sealed class Singleton
{
private static Singleton instance = null;
private static readonly object lockObject = new object();
private Singleton() {}
public static Singleton Instance
{
get
{
lock(lockObject)
{
if (instance == null)
{
instance = new Singleton();
}
}
return instance;
}
}
}- Padrão Factory: O padrão Factory é usado para criar objetos sem expor a lógica de criação ao cliente. No .NET, o padrão Factory é implementado usando uma classe ou método que cria objetos com base em um conjunto de parâmetros. Esse padrão é útil quando você quer criar objetos com base em um conjunto específico de condições e quer esconder a lógica de criação do cliente.
public interface IAnimalFactory
{
IAnimal Create();
}
public class DogFactory : IAnimalFactory
{
public IAnimal Create()
{
return new Dog();
}
}
public class CatFactory : IAnimalFactory
{
public IAnimal Create()
{
return new Cat();
}
}
public interface IAnimal
{
string Speak();
}
public class Dog : IAnimal
{
public string Speak()
{
return "Woof!";
}
}
public class Cat : IAnimal
{
public string Speak()
{
return "Meow!";
}
}- Padrão Builder: O padrão Builder é usado para separar a construção de um objeto complexo de sua representação. No .NET, o padrão Builder é implementado usando uma classe ou método separado que constrói o objeto passo a passo. Esse padrão é útil quando você quer criar objetos complexos com muitos componentes e separar a lógica de construção da representação.
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
public string Address { get; set; }
}
public class PersonBuilder
{
private readonly Person person;
public PersonBuilder()
{
person = new Person();
}
public PersonBuilder WithFirstName(string firstName)
{
person.FirstName = firstName;
return this;
}
public PersonBuilder WithLastName(string lastName)
{
person.LastName = lastName;
return this;
}
public PersonBuilder WithAge(int age)
{
person.Age = age;
return this;
}
public PersonBuilder WithAddress(string address)
{
person.Address = address;
return this;
}
public Person Build()
{
return person;
}
}
- Padrão de Injeção de Dependência: O padrão de Injeção de Dependência é um padrão criacional que oferece uma forma de criar objetos sem precisar conhecer os detalhes de como eles são construídos. Isso é útil quando você precisa criar objetos que têm dependências complexas ou são difíceis de instanciar.
public interface IDataAccessLayer
{
void SaveData(string data);
}
public class SqlDataAccessLayer : IDataAccessLayer
{
public void SaveData(string data)
{
// Implementation of saving data in SQL Server
}
}
public class BusinessLogicLayer
{
private readonly IDataAccessLayer _dataAccessLayer;
public BusinessLogicLayer(IDataAccessLayer dataAccessLayer)
{
_dataAccessLayer = dataAccessLayer;
}
public void SaveData(string data)
{
_dataAccessLayer.SaveData(data);
}
}Padrões de design estrutural são usados para definir as relações entre objetos e como eles podem ser compostos para formar estruturas maiores. Os padrões de design estrutural mais comumente usados no desenvolvimento do .NET são:
- Padrão Adapter: O padrão Adaptador é usado para converter a interface de uma classe em outra interface que os clientes esperam. No .NET, o padrão Adaptador é implementado usando uma classe separada que atua como uma ponte entre duas interfaces incompatíveis. Esse padrão é útil quando você quer usar uma classe que não é compatível com a base de código existente e quer converter sua interface para torná-la compatível.
public interface ITarget
{
void Request();
}
public class Adaptee
{
public void SpecificRequest()
{
Console.WriteLine("Specific request");
}
}
public class Adapter : ITarget
{
private readonly Adaptee _adaptee;
public Adapter(Adaptee adaptee)
{
_adaptee = adaptee;
}
public void Request()
{
_adaptee.SpecificRequest();
}
}- Padrão Decorator: O padrão Decorador é usado para adicionar funcionalidade a um objeto dinamicamente. No .NET, o padrão Decorator é implementado usando uma classe separada que envolve o objeto original e oferece funcionalidades adicionais. Esse padrão é útil quando você quer adicionar funcionalidades a um objeto sem mudar sua interface.
public interface ICoffee
{
string GetDescription();
double GetCost();
}
public class SimpleCoffee : ICoffee
{
public string GetDescription()
{
return "Simple Coffee";
}
public double GetCost()
{
return 1.0;
}
}
public class CoffeeWithMilk : ICoffee
{
private readonly ICoffee _coffee;
public CoffeeWithMilk(ICoffee coffee)
{
_coffee = coffee;
}
public string GetDescription()
{
return _coffee.GetDescription() + ", with milk";
}
public double GetCost()
{
return _coffee.GetCost() + 0.5;
}
}- Padrão Facade: O padrão Facade é usado para fornecer uma interface simples a um sistema complexo. No .NET, o padrão Facade é implementado usando uma classe separada que fornece uma interface simplificada para o sistema existente. Esse padrão é útil quando você quer simplificar a interação com um sistema complexo e quer esconder sua complexidade do cliente.
// Complex subsystem with many parts
public class Subsystem1
{
public void Operation1()
{
Console.WriteLine("Subsystem1: Operation1");
}
public void Operation2()
{
Console.WriteLine("Subsystem1: Operation2");
}
}
public class Subsystem2
{
public void Operation3()
{
Console.WriteLine("Subsystem2: Operation3");
}
public void Operation4()
{
Console.WriteLine("Subsystem2: Operation4");
}
}
public class Subsystem3
{
public void Operation5()
{
Console.WriteLine("Subsystem3: Operation5");
}
public void Operation6()
{
Console.WriteLine("Subsystem3: Operation6");
}
}
// Facade that simplifies the interface to the subsystem
public class Facade
{
private readonly Subsystem1 _subsystem1;
private readonly Subsystem2 _subsystem2;
private readonly Subsystem3 _subsystem3;
public Facade()
{
_subsystem1 = new Subsystem1();
_subsystem2 = new Subsystem2();
_subsystem3 = new Subsystem3();
}
public void Operation()
{
_subsystem1.Operation1();
_subsystem2.Operation4();
_subsystem3.Operation6();
}
}- Padrão Bridge: O padrão Bridge é usado para desacoplar uma abstração de sua implementação, permitindo que eles variem de forma independente. Ele oferece uma forma de criar uma família de classes relacionadas com diferentes implementações. Esse padrão é particularmente útil quando temos múltiplas variações de uma classe que queremos usar de forma intercambiável.
public interface IImplementor
{
void OperationImpl();
}
public class ConcreteImplementorA : IImplementor
{
public void OperationImpl()
{
Console.WriteLine("Concrete Implementor A");
}
}
public class ConcreteImplementorB : IImplementor
{
public void OperationImpl()
{
Console.WriteLine("Concrete Implementor B");
}
}
public abstract class Abstraction
{
protected IImplementor _implementor;
public Abstraction(IImplementor implementor)
{
_implementor = implementor;
}
public virtual void Operation()
{
_implementor.OperationImpl();
}
}
public class RefinedAbstraction : Abstraction
{
public RefinedAbstraction(IImplementor implementor) : base(implementor)
{
}
public override void Operation()
{
_implementor.OperationImpl();
}
}Padrões de Design Comportamental: são um conjunto de 21 padrões de projeto de software que definem e separam a comunicação entre objetos, focando em algoritmos e na atribuição de responsabilidades. Eles aumentam a flexibilidade e a manutenibilidade do código, tornando a interação entre objetos mais eficiente e a arquitetura mais limpa.
- Padrão Observer: O Padrão do Observador é um padrão de design comportamental que permite que um objeto, chamado sujeito, notifique uma lista de observadores quando seu estado muda. Os observadores são então automaticamente notificados e atualizados. Um exemplo típico desse padrão é uma agência de notícias que notifica seus assinantes quando um novo artigo é publicado.
public interface IObserver
{
void Update();
}
public interface ISubject
{
void Attach(IObserver observer);
void Detach(IObserver observer);
void Notify();
}
public class ConcreteSubject : ISubject
{
private List<IObserver> _observers = new List<IObserver>();
private string _state;
public string State
{
get { return _state; }
set
{
_state = value;
Notify();
}
}
public void Attach(IObserver observer)
{
_observers.Add(observer);
}
public void Detach(IObserver observer)
{
_observers.Remove(observer);
}
public void Notify()
{
foreach (IObserver observer in _observers)
{
observer.Update();
}
}
}
public class ConcreteObserver : IObserver
{
private string _name;
private string _observerState;
private ConcreteSubject _subject;
public ConcreteObserver(ConcreteSubject subject, string name)
{
_subject = subject;
_name = name;
}
public void Update()
{
_observerState = _subject.State;
Console.WriteLine($"Observer {_name}'s new state is {_observerState}");
}
}
public static void Main()
{
ConcreteSubject subject = new ConcreteSubject();
ConcreteObserver observerA = new ConcreteObserver(subject, "A");
ConcreteObserver observerB = new ConcreteObserver(subject, "B");
ConcreteObserver observerC = new ConcreteObserver(subject, "C");
subject.Attach(observerA);
subject.Attach(observerB);
subject.Attach(observerC);
subject.State = "New State";
}- Padrão Command: O Padrão de Comando é um padrão de design comportamental que encapsula uma requisição como um objeto, permitindo assim a parametrização de clientes com diferentes requisições, filas e requisições de log, e suporta operações inviáveis. Um exemplo típico desse padrão é um controle remoto para uma TV, onde cada pressão de botão corresponde a um comando diferente.
public interface ICommand
{
void Execute();
}
public class Receiver
{
public void Action()
{
Console.WriteLine("Receiver does some action");
}
}
public class ConcreteCommand : ICommand
{
private Receiver _receiver;
public ConcreteCommand(Receiver receiver)
{
_receiver = receiver;
}
public void Execute()
{
_receiver.Action();
}
}
public class Invoker
{
private ICommand _command;
public void SetCommand(ICommand command)
{
_command = command;
}
public void ExecuteCommand()
{
_command.Execute();
}
}
public static void Main()
{
Invoker invoker = new Invoker();
Receiver receiver = new Receiver();
ConcreteCommand command = new ConcreteCommand(receiver);
invoker.SetCommand(command);
invoker.ExecuteCommand();
}- Padrão Strategy: O Padrão de Estratégia é um padrão de design comportamental que permite a um cliente escolher entre uma família de algoritmos em tempo de execução. Esse padrão é útil quando existem múltiplos algoritmos que podem ser usados para resolver um problema, e a escolha do algoritmo depende do contexto. Um exemplo típico desse padrão é um algoritmo de ordenação que pode ser escolhido com base no tamanho dos dados de entrada.
public interface IStrategy
{
void AlgorithmInterface();
}
public class ConcreteStrategyA : IStrategy
{
public void AlgorithmInterface()
{
Console.WriteLine("ConcreteStrategyA.AlgorithmInterface()");
}
}
public class ConcreteStrategyB : IStrategy
{
public void AlgorithmInterface()
{
Console.WriteLine("ConcreteStrategyB.AlgorithmInterface()");
}
}
public class Context
{
private IStrategy _strategy;
public Context(IStrategy strategy)
{
_strategy = strategy;
}
public void ContextInterface()
{
_strategy.AlgorithmInterface();
}
}
public static void Main()
{
Context context;
context = new Context(new ConcreteStrategyA());
context.ContextInterface();
context = new Context(new ConcreteStrategyB());
context.ContextInterface();
}O TDD - Test-Driven Development, ou em português "Desenvolvimento guiado por testes" ou Desenvolvimento Orientado a testes ou Desenvolvimento digirido por testes, é uma técnica de desenvolvimento de software que se relaciona com o conceito de verificação e validação e se baseia em um ciclo curto de repetições: Primeiramente o desenvolvedor escreve um caso de teste automatizado que define uma melhoria desejada ou uma nova funcionalidade. Então, é produzido código que possa ser validado pelo teste para posteriormente o código ser refatorado para um código sob padrões aceitáveis. Basicamente, ela ajuda a aumentar a produtividade a partir de testes já consolidados. O TDD (Test-Driven Development) foca em um tipo específico de teste chamado teste de unidade. No entanto, ele pode influenciar outros tipos de testes durante o ciclo de desenvolvimento.
Kent Beck, considerado o criador ou o 'descobridor' da técnica, declarou em 2003 que TDD encoraja designs de código simples e inspira confiança. Desenvolvimento dirigido por testes é relacionado a conceitos de programação de XP - Extreme Programming, iniciado em 1999, mas recentemente tem-se criado maior interesse pela mesma em função de seus próprios ideais. Através de TDD, programadores podem aplicar o conceito de melhorar e depurar código legado desenvolvido a partir de técnicas antigas.
O TDD é considerado uma técnica ou metodologia, muito adotada nos times de desenvolvimento. Isso porque ele é direcionado ao desenvolvimento de softwares. Contudo, pelo fato de inverter a ordem dos trabalhos – do teste para o código – é um pouco impopular entre os Devs. No entanto, após pegar o jeito, o desenvolvimento ganha um up, e a técnica traz muitos resultados positivos ao projeto.
O TDD segue a lógica do ciclo: Red, Green e Refactor. Este ciclo é uma abordagem estruturada para escrever e melhorar código de software de maneira incremental, garantindo que ele seja testável, funcional e de alta qualidade. Aqui está uma explicação detalhada de cada fase do ciclo:
🔴 Red: Escreva um teste que apresenta erros, que falhe. Ação: você começa escrevendo um teste automatizado para a funcionalidade que deseja implementar. Este teste é baseado nos requisitos e especificações do que o código deve fazer. Resultado: O teste falha, pois a funcionalidade ainda não foi implementada. A falha confirma que o teste é válido e que a funcionalidade não existe no momento.
🟢 Green: Logo após, escreva um código que passe no teste, que funcione e faça o teste passar. Ação: Escrever a quantidade mínima de código necessário para fazer o teste passar. Nesta fase, o foco está em implementar a funcionalidade de maneira rápida e simples, sem se preocupar muito com a qualidade ou elegância do código. Resultado: O teste passa, indicando que a funcionalidade básica foi implementada corretamente.
🟡 Refactor: Depois disso, "refatorar" o que foi feito, ou seja, eliminar a redundância e melhorar a qualidade do código, ou seja, melhorar e otimizar o código sem alterar sua funcionalidade, mantendo todos os testes passando. Ação: Refatorar o código escrito na fase anterior para torná-lo mais limpo com princípios de Código Limpo (Clean Code), eficiente e fácil de manter. Isso pode incluir a remoção de duplicações, melhoria da legibilidade, e conformidade com padrões de design. Resultado: O código é melhorado sem alterar seu comportamento externo. Os testes (novos e antigos) continuam passando, garantindo que a funcionalidade permanece correta após as melhorias.
A Refatoração é o processo de reestruturar o código de um software para melhorar sua qualidade interna, sem alterar seu comportamento externo. A principal finalidade da refatoração é tornar o código mais limpo, legível, e fácil de manter, otimizando aspectos como desempenho, organização e modularidade. Ela costuma envolver a remoção de duplicação de código, simplificação de estruturas complexas, e melhoria na nomenclatura de variáveis, classes e funções, além de aplicar padrões de design e princípios como o SOLID. Refatorar também ajuda a prevenir a "dívida técnica", que ocorre quando decisões de design ou implementação apressadas criam problemas futuros. Em metodologias ágeis, a refatoração é geralmente integrada ao processo de desenvolvimento contínuo, sendo realizada entre ciclos de implementação de novas funcionalidades. Portanto, a refatoração se encaixa como uma prática regular dentro da fase de desenvolvimento, especificamente na etapa de Integração Contínua (CI), que foca na qualidade do código e na automação de testes.
Por mais de vinte anos, programadores experientes no mundo inteiro contaram com o livro Refatoração: Aperfeiçoando o Design de Códigos Existentes de Martin Fowler para aperfeiçoar o design de códigos existentes e melhorar a manutenibilidade do software, assim como para deixar o código existente mais fácil de entender. Essa nova edição ansiosamente esperada foi atualizada por completo para refletir mudanças vitais no domínio da programação. Refatoração 2ª edição contém um catálogo atualizado das refatorações e inclui exemplos de código JavaScript bem como novos exemplos funcionais que demonstram a refatoração sem classes. Assim como na edição original, este livro explica o que é refatoração, por que você deve refatorar, como reorganizar um código que precise de refatoração e como fazer isso de forma bem-sucedida, independentemente da linguagem usada.
Após ler este livro, você será capaz de:
- Entenda o processo e os princípios básicos da refatoração;
- Aplique rapidamente refatorações convenientes para deixar um programa mais fácil de entender e de alterar;
- Reconheça “maus cheiros” no código que sinalizam oportunidades para refatorar;
- Explore as refatorações, cada uma com suas explicações, a motivação, o mecanismo e exemplos simples;
- Escreva testes robustos para suas refatorações;
- Reconheça as contrapartidas e os obstáculos para a refatoração.
O Desenvolvimento dirigido por testes requer dos desenvolvedores criar testes automatizados que definam requisitos em código antes de escrever o código da aplicação. Os testes contém asserções que podem ser verdadeiras ou falsas. Após as mesmas serem consideradas verdadeiras após sua execução, os testes confirmam o comportamento correto, permitindo os desenvolvedores evoluir e refatorar o código. Normalmente todos os testes são efetuados de forma continua de acordo com o desenvolvimento cada funcionalidade criada deve ser acompanhada de um teste bem descrito e projetado, então deve-se escolher a área do projeto ou requisitos da tarefa para melhor orientar o desenvolvimento destes testes.
Desenvolvedores normalmente usam frameworks de testes, como xUnit, para criar e executar automaticamente uma série de casos de teste.
As empresas esperam que seus colaboradores sejam realmente muito bons em testes unitários e a melhor forma de garantir isso é pedindo TDD. Muitas pessoas aprendem testes de forma muito superficial, mas um profissional que já praticou TDD em alguma codebase real tem uma vantagem sobre os outros, pois já enfrentou diversos problemas e sabe como contorná-los.
Os testes em integração contínua são sobre feedback do software, como a maioria dos métodos ágeis. Feedback é o ponto chave para um desenvolvimento com qualidade, seja ele a nível técnico, de gestão ou pessoal. O Feedback é o ponto chave para um desenvolvimento com qualidade, seja ele a nível técnico, de gestão ou pessoal.
Bom, muito provavelmente não fui eu quem inventou o nome Ciclo de Feedback para desenvolvimento de Software mas estou adicionando o guiado a Testes. Legal mas o que isso quer dizer? Quer dizer que, quando trabalhando no desenvolvimento de uma tarefa qualquer, que seja guiada a testes, nós temos que trabalhar em cima do feedback que os testes nos trazem e não com o pensamento de que temos apenas que codar a
featuree adicionar testes para garanti-las. Realizar uma tarefa guiada a testes com esse pensamento é disperdiçar boa parte do potencial da abordagem do TDD.
O DDD - Domain-Driven Design (Projeto Orientado a Domínio) é um tipo de modelagem de software e um design de software orientado a objetos que procura reforçar conceitos e boas práticas relacionadas à OOP e surgiu como uma resposta às dificuldades enfrentadas por desenvolvedores ao lidarem com sistemas complexos, especialmente em domínios de negócio onde a lógica e os requisitos mudam frequentemente. Isso vem em contrapartida com o uso comum do Data-Driven Design (Projeto Orientado a Dados), que a maioria dos desenvolvedores usa sem mesmo ter consciência disso. O DDD nos permite planejar uma arquitetura de microsserviços decompondo o sistema maior em unidades independentes, compreendendo as responsabilidades de cada uma e identificando seus relacionamentos, ele não é um design pattern específico, mas sim uma importante abordagem de design de software, com foco na modelagem de software para corresponder a um domínio de acordo com as informações dos especialistas desse domínio. O Domain-Driven Design (DDD) surgiu como uma metodologia revolucionária para a modelagem de software, desenvolvida com o intuito de refinar e otimizar a correspondência entre o design do software e o domínio do software e o domínio do problema que ele busca resolver.
Os microsserviços são a forma mais escalável de desenvolver software. Mas você precisa de um bom design que permita que as equipes de desenvolvedores trabalhem de forma autônoma e implementem sem atrapalhar umas às outras, caso contrário, você perderá os benefícios de escalabilidade. O DDD ajuda a delimitar responsabilidades claras entre os serviços, o que permite que equipes atuem de forma independente e coordenada.
Foi popularizado por Eric Evans em seu livro Domain-Driven Design: Tackling Complexity in the Heart of Software, publicado em 2003. Esse livro não é leve, especialmente se você ainda está no início da jornada. Ele exige uma certa base em desenvolvimento orientado a objetos, arquitetura de software e experiência prática com projetos reais. Geralmente, ele é mais proveitoso depois que você já trabalhou em sistemas mais complexos ou com arquitetura em camadas.
Sem levar em conta o DDD, as técnicas de modelagem de domínio são métodos utilizados na engenharia de software para compreender e representar o domínio de um problema específico. O domínio refere-se à área de conhecimento, contexto ou setor de negócios em que o software está sendo desenvolvido. A modelagem de domínio tem como objetivo capturar os conceitos, regras e relacionamentos do domínio em um formato compreensível e utilizável pelos desenvolvedores. Então, o DDD (Domain-Driven Design) é uma abordagem para o desenvolvimento de software que combina conceitos de design de software e técnicas de modelagem de domínio. Não é considerado um design pattern específico, mas sim uma abordagem geral para projetar e estruturar sistemas de software. Domain-Driven Design (DDD) é um método de design de software em que os desenvolvedores constroem modelos para entender os requisitos de negócios de um domínio. Esses modelos servem como base conceitual para o desenvolvimento de software.
No entanto, suas raízes vêm de práticas e ideias que estavam sendo discutidas na indústria desde os anos 1990. Durante esse período, muitas empresas estavam adotando metodologias ágeis e enfrentando problemas ao construir sistemas que não apenas funcionassem, mas que também fossem fáceis de entender, modificar e expandir. Um dos grandes desafios era a chamada "lacuna semântica" entre os especialistas de domínio (pessoas que entendem o negócio) e os desenvolvedores (que implementam soluções técnicas). Essa lacuna frequentemente levava a softwares que funcionavam de forma errada ou que eram difíceis de adaptar a mudanças nos requisitos.
A ideia inicial do DDD é voltar à uma modelagem OO mais pura, por assim dizer. Devemos esquecer de como os dados são persistidos e nos preocupar em como representar melhor as necessidades de negócio em classes e comportamentos (métodos). Isso significa que em DDD um Cliente pode não ter um setter para os seus atributos comuns, mas pode ter métodos com lógica de negócio que neste domínio de negócio pertencem ao cliente, como void associarNovoCartao(Cartao) ou Conta recuperarInformacoesConta(). Em resumo, as classes modeladas e os seus métodos deveriam representar o negócio da empresa, usando inclusive a mesma nomenclatura. A persistência dos dados é colocada em segundo plano, sendo apenas uma camada complementar.
O DDD nasceu da necessidade de aproximar esses dois mundos. Eric Evans observou que o software bem-sucedido em contextos complexos era construído em torno de um modelo de domínio que capturava com precisão o conhecimento do negócio. Ele também percebeu que os sistemas mais sustentáveis utilizavam linguagens comuns entre especialistas e desenvolvedores, além de técnicas para isolar a complexidade e tornar o código mais alinhado com as regras do domínio.
O DDD formalizou essas práticas ao introduzir conceitos como Ubiquitous Language (Linguagem Ubíqua), que promove a criação de uma linguagem compartilhada entre todas as partes interessadas, e Bounded Contexts, que ajudam a dividir sistemas grandes e complexos em partes menores e mais compreensíveis. Além disso, o DDD trouxe atenção para padrões arquiteturais que dão suporte ao domínio, como Entidades, Agregados, Repositórios e Serviços de Domínio, estabelecendo um design centrado na lógica de negócios em vez de nas tecnologias subjacentes.
Em essência, o DDD surgiu para enfrentar a complexidade inerente ao desenvolvimento de software em domínios desafiadores, permitindo que os sistemas sejam projetados de forma que o código seja uma expressão direta das regras e processos do negócio. Com o tempo, o DDD ganhou popularidade e passou a ser usado em diversos contextos, especialmente em sistemas corporativos onde o domínio de negócio é complexo e sujeito a constantes mudanças.
O DDD enfatiza a compreensão profunda do domínio do problema e o uso de uma linguagem ubíqua compartilhada entre as equipes de desenvolvimento e especialistas do domínio. Ele propõe a organização do código em torno do domínio do problema, separando-o dos detalhes técnicos e infraestrutura.
Embora o DDD não seja um design pattern em si, ele pode ser combinado com vários design patterns e princípios de design, como Agregado, Repositório, Especificação, Event Sourcing, entre outros. O DDD fornece diretrizes e conceitos para ajudar na criação de uma arquitetura de software robusta e flexível.
Portanto, podemos dizer que o DDD é uma abordagem de design e uma metodologia de modelagem que pode ser aplicada em diferentes arquiteturas de software, como arquitetura em camadas, arquitetura hexagonal, arquitetura de microsserviços, entre outras. Ele fornece princípios e práticas para projetar e estruturar o código em torno do domínio do problema, visando um modelo de domínio rico, desacoplamento e flexibilidade.
É uma abordagem mais ampla para o design de software que abrange vários conceitos e técnicas. DDD enfatiza a modelagem do domínio, a colaboração entre especialistas do domínio e desenvolvedores, e a criação de um código baseado em um entendimento profundo do domínio do problema.
No contexto do DDD, existem design patterns específicos que são frequentemente utilizados para ajudar a implementar os conceitos e princípios do DDD. Alguns desses padrões incluem:
-
Agregado: Se refere a um padrão de design que agrupa um conjunto de objetos relacionados em uma única unidade coesa. O Agregado é uma das principais construções utilizadas para modelar e organizar o domínio em DDD;
-
Repositório:;
-
Serviço de Domínio:;
-
Value Object:;
-
Entidade:;
-
Factory:;
-
Especificação:;
-
Event Sourcing:;
Esses padrões, juntamente com outros conceitos e técnicas, podem ser aplicados para construir uma arquitetura que segue os princípios do DDD. O DDD, portanto, não é um design pattern em si, mas uma abordagem que pode ser implementada usando diversos padrões de design específicos.
Quando não usar DDD? Às vezes só é necessário um CRUD! DDD não é uma solução para tudo. A maioria dos sistemas possui uma boa parte composta por cadastros básicos (CRUD) e não seria adequado usar DDD para isso.
O DDD deve ajudar na modelagem das classes mais importantes e mais centrais do sistema de forma e diminuir a complexidade e ajudar na manutenção das mesmas, afinal este é o objetivo dos princípios de orientação a objetos.
Outro ponto é sobre nós desenvolvedores estarmos compartilhando dados com outros sistemas, as rotinas de integração que recebem ou disponibilizam dados para outros sistemas não devem ser "inteligentes". Muitos desenvolvedores acabam modelando suas classes de negócios tentando resolver as questões internas do sistema e, ao mesmo tempo, pensando em como essas classes serão expostas para outros sistemas. Padrões como DTO (Data Transfer Object) que usam objetos "burros" são mais adequados para isso.
Portanto, o DDD não tenta resolver todos os problemas de todas as camadas de um sistema. Seu foco é na modelagem das entidades principais de negócio usando a linguagem adequada daquele domínio para facilitar a manutenção, extensão e entendimento. Particularmente, eu não seguiria à risca o padrão, até porque existem inúmeros padrões e variações de modelagem OO. Estude os princípios por detrás desses padrões, pois eles são geralmente parecidos e veja o que funciona melhor para cada projeto.
O BDD - Behavior-Driven Development (Desenvolvimento Orientado a Comportamento), é uma metodologia de desenvolvimento ágil que tem como foco a colaboração entre desenvolvedores, QA (Quality Assurance) e partes interessadas não técnicas para criar uma compreensão compartilhada do comportamento desejado de um software. O BDD é uma evolução do TDD (Test-Driven Development) e adiciona uma ênfase maior na comunicação e na clareza dos requisitos. Em resumo, o BDD promove uma abordagem colaborativa para o desenvolvimento de software, focando em comportamentos e resultados esperados do sistema, o que ajuda a garantir que o software entregue atenda às necessidades reais dos usuários e stakeholders.
Aqui estão os componentes chave do BDD:
-
Foco no Comportamento: Em vez de se concentrar apenas na implementação técnica e nos testes de unidade, o BDD foca em como o software deve se comportar sob várias condições, incluindo o comportamento do usuário final.
-
Linguagem Ubíqua (Ubiquitous Language): Utiliza uma linguagem comum (frequentemente baseada em linguagens naturais como o inglês) que pode ser compreendida por todos os membros da equipe, incluindo desenvolvedores, QA, e stakeholders não técnicos. Isso ajuda a reduzir ambiguidades e garantir que todos tenham a mesma compreensão dos requisitos. A Linguagem Ubíqua (Ubiquitous Language) é um conceito central no Design Orientado a Domínio (DDD) que visa criar uma linguagem comum entre todos os envolvidos em um projeto, seja para os especialistas no domínio, desenvolvedores, ou mesmo os usuários finais. Essa linguagem comum facilita a comunicação e colaboração, reduzindo a possibilidade de mal-entendidos e melhorando a qualidade do desenvolvimento.
-
Especificações Executáveis: No BDD, os requisitos são escritos em forma de especificações que podem ser executadas como testes. Essas especificações geralmente seguem um formato estruturado, como Gherkin, que usa palavras-chave como "
Given" (Dado), "When" (Quando), e "Then" (Então) para descrever cenários de teste.Given(Dado): Descreve o contexto inicial ou o estado do sistema antes de uma ação específica.When(Quando): Descreve a ação ou evento que ocorre.Then(Então): Descreve o resultado esperado ou o comportamento do sistema após a ação.
Exemplo: Login no Sistema
Feature: Login no Sistema
Scenario: Login com credenciais válidas
Given: o usuário está na página de login
When: o usuário insere suas credenciais válidas
Then: o usuário é redirecionado para a página inicialExemplo 2: Pesquisar produto
Feature: Pesquisar produto
Scenario: Buscar produto com sucesso
Given:
When:
Then:- Ferramentas de BDD: Existem várias ferramentas que suportam BDD, ajudando a automatizar as especificações executáveis. Algumas das ferramentas populares incluem Cucumber (para várias linguagens como Java, Ruby), SpecFlow (para .NET), Behave (para Python), entre outras.
- Benefícios do BDD:
-
Melhor Comunicação: Facilita a comunicação entre todos os membros da equipe, garantindo que todos entendam os requisitos de maneira clara e compartilhada.
-
Desenvolvimento Orientado a Valor: Foca no que realmente importa para os usuários finais e stakeholders, ajudando a priorizar o desenvolvimento de funcionalidades de maior valor.
-
Menos Retrabalho: Reduz ambiguidades nos requisitos, diminuindo o risco de desenvolvimento de funcionalidades incorretas ou desnecessárias.
-
Documentação Viva: As especificações atuam como uma documentação viva que está sempre em sincronia com o comportamento atual do sistema. O Moq e XUnit.net são ferramentas distintas para testes em .NET, em resumo, Moq simula dependências; XUnit.net executa testes:
-
-
Moq: Um framework de mocking usado para criar objetos simulados (mocks) de dependências, permitindo testar unidades isoladas de código, como classes e métodos, sem precisar interagir com implementações reais.
-
XUnit.net: Um framework de teste de unidade que define e executa os testes. Ele fornece as anotações e funcionalidades para escrever testes e verificar os resultados (como
[Fact]eAssert).
Antes de passar para a explicação do desenvolvimento orientado a testes, quero começar com alguns exemplos imediatamente. De fato, a melhor explicação de por que precisaríamos de algum tipo de técnica sofisticada é mostrar a você como facilmente podemos cair em centenas de armadilhas que nos aguardam em todos os lugares.
Escrevemos um pedaço de código e achamos que está tudo bem. Saímos do nosso local de trabalho. Dormimos bem por um tempo e então o telefone toca:
- Quem é?
- Sou eu. Diga ao seu cliente que seu software não funciona, perderemos dez mil dólares por hora.
- Seria muito gentil se você se apressasse e consertasse tudo.
- Então, Sr. Cliente, vá embora.É assim que frequentemente descobrimos que nosso código é uma porcaria e precisa ser reescrito. Vamos demonstrar que o primeiro exemplo que vou mostrar a vocês diz respeito à implementação chamada formato canônico (Canonical form).
Imagine que você precisa implementar um algoritmo de busca (search algorithm) rápida para uma loja online de música. Nesse caso, você pode precisar armazenar em cache os resultados da busca e, para fazer isso corretamente, precisa transformar os termos de busca em um formato canônico. Em outras palavras, você precisa converter todas as letras para maiúsculas (UPPERCASE) e classificar as palavras em ordem alfabética.
Você precisa fazer isso porque os usuários podem ordenar os termos de busca aleatoriamente. Iniciar o aplicativo do artista primeiro e depois o nome da música, ou vice-versa. Eles podem digitar as letras dos seus termos de busca em letras maiúsculas e minúsculas simplesmente por serem seres humanos e fazer isso involuntariamente.
Portanto, a mesma música pode ser pesquisada por centenas de termos escritos de maneiras diferentes. É claro que precisamos reduzir todos os termos de busca a um formato canônico.
Como eu já disse, neste caso, vamos converter todas as letras para maiúsculas e minúsculas e classificar as palavras em ordem alfabética. Tudo é bem simples, certo?
Qualquer desenvolvedor pode escrever um algoritmo assim em dez segundos. Sou um desenvolvedor avançado, então abri o editor e comecei a implementar aquele algoritmo trivial.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
// TDD Case: Search Algorithm
namespace TDD_Case {
// Canonical form ordening
public class NaiveCanonicalizer {
public static string GetCanonicalizerForm(string searchTerm) {
return searchTerm
.Split(new[]{' '})
.Select(x=>x.ToUpper())
.OrderBy(x=>x)
Aggregate((x, y) => x + " " + y);
}
}
}O algoritmo é bem simples. Vamos definir a função public static, para a string, pois ela vai receber a entrada será uma busca ou um termo de busca. Primeiramente, devo dividir a entrada por espaço interno. Depois, transformar as letras em maiúsculas e usar a operação de seleção de enfileiramento, X para maiúsculas. Depois, ordenarei as letras em ordem alfabética e todas as palavras juntas. Chamando a função de link aggregation, que apenas concatena as palavras. Neste caso, usando este espaço como delimitador entre as palavras. X mais Espaço X Y. Ótimo, terminei!
Eu até posso verificar a solução. Vamos para a função principal e chamar o método "just 3" com algumas strings diferentes. Vamos fazer isso na função principal, então console a linha correta e eu chamarei o valete.
Os erros canônicos estão bem aqui. Obtenha a forma canônica e eu passarei nos três casos. Eu amo essa música. Ela se chama Wonderful Life, da Katy, seu sol. Meus sonhos pairam brilham no céu. Meu O chamado obtém a forma canônica passando strings absolutamente diferentes, podemos executar essa alegação e verificar a saída.
NLog é um mecanismo de log avançado para .NET, multi-plataforma, que permite o registro de eventos em diferentes níveis de severidade, como Debug, Info, Warn, Error e Fatal. Ele suporta vários alvos de log, como arquivos, bases de dados, redes e muito mais. Ele é personalizável e extensível, permitindo que os desenvolvedores ajustem a saída do log de acordo com as necessidades da aplicação. Ele é uma ferramenta importante para o desenvolvimento de aplicações robustas e estáveis. Ele ajuda a monitorar e solucionar problemas de aplicações em tempo real. Possui uma variedade de recursos, como:
- Registrador de eventos flexível e personalizável;
- Múltiplos alvos de log, como arquivos, bases de dados e redes;
- Suporte a diferentes níveis de severidade de log;
- Filtros e regras de log personalizáveis;
- Suporte a registradores de eventos assíncronos;
- Integração com frameworks .NET populares.
Serilog é uma biblioteca de logging para aplicativos .NET que permite a gravação estruturada de logs. Diferente de sistemas de logging tradicionais, que geralmente gravam logs como texto simples, o Serilog permite que os dados de log sejam estruturados e enriquecidos com propriedades adicionais. Isso facilita a consulta, análise e correlação de eventos nos logs. Serilog é uma ferramenta poderosa e flexível para logging em aplicativos .NET, permitindo registros estruturados e integrando-se facilmente com diversos sistemas de armazenamento e análise de logs.
Principais Características do Serilog:
-
Logging Estruturado: Em vez de apenas texto, Serilog permite registrar dados em um formato estruturado, como JSON. Isso facilita a busca e análise dos logs.
-
Sinks: Serilog suporta múltiplos "sinks", que são destinos onde os logs podem ser enviados. Exemplos de sinks incluem arquivos, bancos de dados, consoles, sistemas de monitoramento, e serviços de cloud como Azure e AWS.
-
Enriquecimento de Logs: Serilog permite adicionar propriedades extras aos logs, como IDs de correlação, informações de usuário, contexto de execução, etc.
-
Configuração Flexível: Pode ser configurado por código ou usando arquivos de configuração como JSON ou XML.
-
Suporte para Múltiplos Formatos: Além de JSON, Serilog pode gravar logs em formatos como texto simples, XML, e outros, dependendo do sink usado.
-
Desempenho: É otimizado para alto desempenho e pode ser usado em aplicativos que exigem logging em tempo real.
Exemplo de Uso Básico:
Aqui está um exemplo simples de como configurar e usar o Serilog em um aplicativo .NET:
using Serilog;
class Program
{
static void Main(string[] args)
{
// Configurando o Serilog
Log.Logger = new LoggerConfiguration()
.WriteTo.Console()
.WriteTo.File("logs/myapp.txt", rollingInterval: RollingInterval.Day)
.CreateLogger();
// Usando o Serilog para registrar logs
Log.Information("Hello, Serilog!");
Log.Warning("This is a warning.");
Log.Error("An error occurred.");
// Finalizando o Logger
Log.CloseAndFlush();
}
}Neste exemplo, o Serilog é configurado para escrever logs tanto no console quanto em um arquivo, com rotação diária dos arquivos de log. Os métodos Log.Information, Log.Warning e Log.Error são usados para registrar mensagens de log com diferentes níveis de severidade.
Ou seja, uma configuração de solução ASP.NET Core com opiniões fortes para criar aplicações web usando os princípios da Arquitetura Limpa e do Design Orientado a Domínio.
Hoje em dia, estamos produzindo mais código do que nunca! Microsserviços, minisserviços, microsites, monólitos (modulares)... não importa o quê. Estamos recebendo cada vez mais padrões, padrões e práticas diariamente – o que é bom...? Bem, eu acho que sim, mas leva muito tempo para aprender e configurar nossas soluções para mantê-las atualizadas.
Esta configuração ASP.NET segue todas as práticas modernas mais recentes e possui algumas proteções integradas para proteger nosso código da sua maior ameaça: nós mesmos! Todos nós já passamos por aqueles momentos em que deixamos nossos padrões de lado e o resultado é um código persistente e com mau cheiro.
Um projeto de modelo é ótimo para estruturar todo o seu código boiler plate, para que você possa se concentrar rapidamente no problema específico que sua aplicação está tentando resolver. Com este projeto de modelo, podemos começar rapidamente a construir novos aplicativos com todas as "coisas boas" prontas para uso! Minha opinião sobre "as coisas boas" é bastante, bem... opinativa. Aqui estão os tipos de coisas que incorporei:
- Arquitetura Limpa
- Design Orientado a Domínio
SpecFlow
Clean Architecture in ASP .NET Core Web API: A Guide to Building Scalable, Maintainable Web API using ASP .NET Core
O termo "Clean Architecture" tem se tornado cada vez mais popular no desenvolvimento de software nos últimos anos. Clean Architecture é um padrão de design de software que prioriza a separação de preocupações, facilitando a manutenção, o teste e a evolução de uma aplicação ao longo do tempo. Vamos analisar a Arquitetura Limpa e como ela pode ser aplicada a ASP.NET aplicações Core.



















