<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Bruno Pizol Camargo</title>
    <description>The latest articles on DEV Community by Bruno Pizol Camargo (@brunopizol).</description>
    <link>https://dev.to/brunopizol</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1284300%2Fc81ed9c0-cc54-44e8-9c27-8b90c70c3999.jpeg</url>
      <title>DEV Community: Bruno Pizol Camargo</title>
      <link>https://dev.to/brunopizol</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/brunopizol"/>
    <language>en</language>
    <item>
      <title>Introdução aos Princípios do SQL: Fundamentos Teóricos e Práticos</title>
      <dc:creator>Bruno Pizol Camargo</dc:creator>
      <pubDate>Fri, 10 May 2024 12:57:06 +0000</pubDate>
      <link>https://dev.to/brunopizol/introducao-aos-principios-do-sql-fundamentos-teoricos-e-praticos-1j0j</link>
      <guid>https://dev.to/brunopizol/introducao-aos-principios-do-sql-fundamentos-teoricos-e-praticos-1j0j</guid>
      <description>&lt;p&gt;O SQL (Structured Query Language), ou Linguagem de Consulta Estruturada, é uma ferramenta poderosa e essencial para qualquer pessoa que trabalhe com bancos de dados relacionais. Se você é um iniciante ou um profissional experiente, compreender os princípios fundamentais do SQL é fundamental para interagir eficazmente com os dados. Neste artigo, vamos explorar desde os conceitos básicos até os tópicos mais avançados do SQL, incluindo design de banco de dados, criação de tabelas e execução de consultas básicas.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;O que é SQL?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Antes de mergulharmos nos detalhes, é importante entender o que exatamente é o SQL. Essa linguagem é utilizada para realizar diversas operações em bancos de dados relacionais, desde a criação e modificação da estrutura do banco de dados até a manipulação e consulta dos dados armazenados.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Banco de dados relacional vs. não relacional&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Os bancos de dados podem ser estruturados de diferentes maneiras, sendo os mais comuns os bancos de dados relacionais e não relacionais. No modelo relacional, os dados são organizados em tabelas, enquanto no não relacional, os dados são armazenados em arquivos. O SQL é principalmente utilizado em bancos de dados relacionais, devido à sua capacidade de consultar e manipular dados de forma eficiente através de tabelas.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;As Linguagens do SQL&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;O SQL é composto por várias linguagens, cada uma com seu propósito específico:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;DDL (Data Definition Language)&lt;/strong&gt;: Utilizada para definir a estrutura do banco de dados, incluindo a criação, alteração e exclusão de tabelas e outros objetos.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DML (Data Manipulation Language)&lt;/strong&gt;: Responsável pela manipulação dos dados dentro das tabelas, incluindo inserção, atualização e exclusão de registros.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DQL (Data Query Language)&lt;/strong&gt;: Utilizada para consultar dados dentro das tabelas, através do comando SELECT.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DCL (Data Control Language)&lt;/strong&gt;: Responsável por controlar os privilégios de acesso aos dados, incluindo a concessão e revogação de permissões.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DTL (Data Transaction Language)&lt;/strong&gt;: Utilizada para controlar as transações no banco de dados, garantindo a consistência e integridade dos dados.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Conceitos Fundamentais do SQL&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Chave Primária&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Uma chave primária é fundamental para a integridade dos dados em um banco de dados relacional. Ela serve como um identificador exclusivo para cada registro em uma tabela. Ao garantir que cada registro tenha uma chave primária única, podemos evitar a inserção de dados duplicados e garantir a unicidade dos dados.&lt;/p&gt;

&lt;p&gt;Além de garantir a unicidade dos registros, as chaves primárias são usadas internamente pelo sistema de gerenciamento de banco de dados (SGBD) para otimizar operações de pesquisa e recuperação de dados. Os SGBDs geralmente criam índices automaticamente para chaves primárias, o que acelera a busca e a manipulação de dados, resultando em melhor desempenho em consultas.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Chave Composta&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Uma chave composta é uma combinação de duas ou mais colunas que juntas formam uma chave única para identificar os registros em uma tabela. Embora as chaves primárias simples sejam mais comuns, as chaves compostas são úteis em cenários onde uma única coluna não é suficiente para garantir a unicidade dos registros.&lt;/p&gt;

&lt;p&gt;O uso de chaves compostas pode melhorar o desempenho em consultas que envolvem várias colunas na cláusula WHERE, pois o índice formado pela chave composta pode ser mais seletivo, reduzindo o número de linhas a serem pesquisadas. No entanto, o uso de chaves compostas também pode aumentar a complexidade do modelo de dados e exigir cuidados extras ao projetar consultas e realizar operações de manutenção.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Chave Estrangeira&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;As chaves estrangeiras estabelecem relacionamentos entre as tabelas de um banco de dados relacional, permitindo a integridade referencial e a manutenção da consistência dos dados. Uma chave estrangeira em uma tabela faz referência à chave primária de outra tabela, criando um vínculo entre elas.&lt;/p&gt;

&lt;p&gt;Ao usar chaves estrangeiras, podemos garantir que os dados relacionados estejam sempre em sincronia e que não haja registros órfãos (registros em uma tabela referenciando registros ausentes em outra tabela). Isso facilita a manutenção e a manipulação dos dados, garantindo que as operações de inserção, atualização e exclusão sejam realizadas de forma consistente.&lt;/p&gt;

&lt;p&gt;No entanto, ao projetar esquemas de banco de dados com chaves estrangeiras, devemos estar cientes de possíveis impactos no desempenho, especialmente em operações de inserção e exclusão em tabelas com muitas dependências. Índices adequados e estratégias de normalização/desnormalização podem ser aplicados para mitigar esses impactos.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Relacionamentos&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Os relacionamentos entre tabelas são a essência dos bancos de dados relacionais, permitindo a representação de dados complexos e a construção de modelos de dados robustos. Existem três tipos principais de relacionamentos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;1 para 1&lt;/strong&gt;: Cada registro em uma tabela está associado a apenas um registro em outra tabela. Esse tipo de relacionamento é útil para dividir dados em entidades separadas, evitando a redundância e garantindo a consistência dos dados. Embora menos comum, ele pode ser útil em cenários onde certos atributos são opcionais ou podem ser compartilhados entre várias entidades.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;1 para muitos&lt;/strong&gt;: Um registro em uma tabela pode estar associado a vários registros em outra tabela. Esse é o tipo de relacionamento mais comum e é amplamente utilizado para representar hierarquias e associações de muitos para um. Por exemplo, um cliente pode ter vários pedidos associados a ele.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Muitos para muitos&lt;/strong&gt;: Vários registros em uma tabela podem estar associados a vários registros em outra tabela. Esse tipo de relacionamento é modelado usando uma tabela de junção, que contém chaves estrangeiras para ambas as tabelas relacionadas. Por exemplo, em um sistema de gerenciamento escolar, vários alunos podem estar matriculados em vários cursos.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Tópicos Avançados do SQL&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Além dos conceitos básicos, existem tópicos mais avançados que podem ser explorados no SQL, incluindo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tipos de Dados&lt;/strong&gt;: O SQL oferece uma variedade de tipos de dados para armazenar diferentes tipos de informações, como números, textos e datas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Estruturas e Condições&lt;/strong&gt;: Utilizadas para filtrar e organizar os resultados das consultas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JOIN&lt;/strong&gt;: Utilizado para combinar dados de duas ou mais tabelas com base em uma condição especificada.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ACID&lt;/strong&gt;: Conjunto de propriedades que garantem a consistência e integridade dos dados em transações.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stored Procedures e Triggers&lt;/strong&gt;: Procedimentos armazenados e gatilhos que permitem automatizar tarefas e executar ações em resposta a eventos específicos no banco de dados.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Tipos de Dados&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;O SQL oferece uma ampla gama de tipos de dados para armazenar diferentes tipos de informações. Alguns dos tipos de dados comuns incluem:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;INTEGER&lt;/strong&gt;: Para armazenar números inteiros.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;VARCHAR&lt;/strong&gt;: Para armazenar cadeias de caracteres de comprimento variável.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DATE&lt;/strong&gt;: Para armazenar datas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DECIMAL&lt;/strong&gt;: Para armazenar números decimais precisos.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Exemplo de criação de tabela usando diferentes tipos de dados:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;Funcionarios&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;ID&lt;/span&gt; &lt;span class="nb"&gt;INTEGER&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Nome&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;DataContratacao&lt;/span&gt; &lt;span class="nb"&gt;DATE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Salario&lt;/span&gt; &lt;span class="nb"&gt;DECIMAL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Estruturas e Condições&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;As estruturas e condições no SQL são usadas para filtrar e organizar os resultados das consultas. Algumas das estruturas comuns incluem:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;WHERE&lt;/strong&gt;: Utilizado para filtrar os resultados com base em uma condição especificada.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ORDER BY&lt;/strong&gt;: Utilizado para classificar os resultados com base em uma ou mais colunas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GROUP BY&lt;/strong&gt;: Utilizado para agrupar os resultados com base em uma ou mais colunas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HAVING&lt;/strong&gt;: Utilizado para filtrar os resultados de um GROUP BY.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Exemplo de consulta usando estruturas e condições:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;Nome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Salario&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;Funcionarios&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;Salario&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;50000&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;Salario&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Joins no SQL&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Os joins são usados para combinar dados de duas ou mais tabelas com base em uma condição relacionada. Existem vários tipos de joins disponíveis no SQL, cada um com um propósito específico. Vamos explorar e exemplificar cada tipo:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;INNER JOIN&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;O INNER JOIN retorna apenas os registros que têm uma correspondência nas duas tabelas sendo combinadas. Ele combina as linhas quando a condição especificada é atendida em ambas as tabelas.&lt;/p&gt;

&lt;p&gt;Exemplo de INNER JOIN:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;Funcionarios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Nome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Departamentos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Nome&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;NomeDepartamento&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;Funcionarios&lt;/span&gt;
&lt;span class="k"&gt;INNER&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;Departamentos&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;Funcionarios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DepartamentoID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Departamentos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neste exemplo, apenas os funcionários que estão associados a um departamento válido serão retornados.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;LEFT JOIN (OUTER JOIN)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;O LEFT JOIN retorna todos os registros da tabela à esquerda do join e os registros correspondentes da tabela à direita do join. Se não houver correspondência, os valores NULL são retornados para as colunas da tabela à direita.&lt;/p&gt;

&lt;p&gt;Exemplo de LEFT JOIN:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;Funcionarios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Nome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Departamentos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Nome&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;NomeDepartamento&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;Funcionarios&lt;/span&gt;
&lt;span class="k"&gt;LEFT&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;Departamentos&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;Funcionarios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DepartamentoID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Departamentos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neste exemplo, todos os funcionários serão retornados, mesmo que não estejam associados a um departamento. Se um funcionário não estiver associado a um departamento, o valor "NULL" será exibido na coluna "NomeDepartamento".&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;RIGHT JOIN (OUTER JOIN)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;O RIGHT JOIN é o oposto do LEFT JOIN. Ele retorna todos os registros da tabela à direita do join e os registros correspondentes da tabela à esquerda do join. Se não houver correspondência, os valores NULL são retornados para as colunas da tabela à esquerda.&lt;/p&gt;

&lt;p&gt;Exemplo de RIGHT JOIN:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;Funcionarios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Nome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Departamentos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Nome&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;NomeDepartamento&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;Funcionarios&lt;/span&gt;
&lt;span class="k"&gt;RIGHT&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;Departamentos&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;Funcionarios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DepartamentoID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Departamentos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neste exemplo, todos os departamentos serão retornados, mesmo que não tenham funcionários associados a eles. Se um departamento não tiver funcionários associados, o valor "NULL" será exibido na coluna "Nome".&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;FULL JOIN (OUTER JOIN)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;O FULL JOIN retorna todos os registros quando houver uma correspondência em uma das tabelas. Ele combina os resultados do LEFT JOIN e RIGHT JOIN. Se não houver correspondência, os valores NULL serão retornados para as colunas da tabela sem correspondência.&lt;/p&gt;

&lt;p&gt;Exemplo de FULL JOIN:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;Funcionarios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Nome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Departamentos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Nome&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;NomeDepartamento&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;Funcionarios&lt;/span&gt;
&lt;span class="k"&gt;FULL&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;Departamentos&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;Funcionarios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DepartamentoID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Departamentos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neste exemplo, todos os funcionários e todos os departamentos serão retornados, combinando os resultados do LEFT e RIGHT JOIN. Se um funcionário não estiver associado a um departamento ou vice-versa, o valor "NULL" será exibido na coluna correspondente.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;CROSS JOIN&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;O CROSS JOIN retorna o produto cartesiano de duas tabelas, ou seja, combina cada linha da primeira tabela com cada linha da segunda tabela. Não há uma condição de junção especificada no CROSS JOIN.&lt;/p&gt;

&lt;p&gt;Exemplo de CROSS JOIN:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;Funcionarios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Nome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Departamentos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Nome&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;NomeDepartamento&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;Funcionarios&lt;/span&gt;
&lt;span class="k"&gt;CROSS&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;Departamentos&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neste exemplo, cada funcionário será combinado com cada departamento, resultando em todas as possíveis combinações entre os funcionários e os departamentos. Este tipo de junção é útil quando se deseja combinar todas as linhas de uma tabela com todas as linhas de outra tabela.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Self Join&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Um Self Join é uma operação em que uma tabela é combinada com ela mesma. É útil quando se deseja comparar linhas dentro da mesma tabela.&lt;/p&gt;

&lt;p&gt;Exemplo de Self Join:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;f1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Nome&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;NomeFuncionario&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;f2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Nome&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;Gerente&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;Funcionarios&lt;/span&gt; &lt;span class="n"&gt;f1&lt;/span&gt;
&lt;span class="k"&gt;INNER&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;Funcionarios&lt;/span&gt; &lt;span class="n"&gt;f2&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;f1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GerenteID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neste exemplo, a tabela de funcionários é combinada consigo mesma para encontrar os funcionários e seus respectivos gerentes. O Self Join é realizado associando a tabela a um alias (f1 e f2, neste caso) para distinguir entre as diferentes instâncias da mesma tabela.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Joins com Condições Complexas&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Além das junções simples baseadas em uma única condição de igualdade, é possível realizar junções com condições mais complexas, utilizando operadores lógicos como AND e OR.&lt;/p&gt;

&lt;p&gt;Exemplo de Join com Condição Complexa:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;Pedidos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Clientes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Nome&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;NomeCliente&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;Pedidos&lt;/span&gt;
&lt;span class="k"&gt;INNER&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;Clientes&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;Pedidos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ClienteID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Clientes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;Pedidos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ValorTotal&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;Clientes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Tipo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'VIP'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neste exemplo, estamos combinando a tabela de Pedidos com a tabela de Clientes com base na condição de igualdade do ID do cliente. Além disso, estamos aplicando condições adicionais usando a cláusula WHERE para filtrar os resultados apenas para pedidos com um valor total superior a 1000 e para clientes do tipo 'VIP'.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Subconsultas Correlacionadas&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Subconsultas correlacionadas são subconsultas em que a subconsulta interna faz referência a uma ou mais colunas da consulta externa. Elas são úteis quando precisamos comparar valores de uma tabela com os valores de outra tabela na mesma consulta.&lt;/p&gt;

&lt;p&gt;Exemplo de Subconsulta Correlacionada:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;Nome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;Pedidos&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;ClienteID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Clientes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;TotalPedidos&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;Clientes&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neste exemplo, a subconsulta na cláusula SELECT conta o número total de pedidos para cada cliente. A condição da subconsulta faz referência à coluna ClienteID da tabela de Pedidos e compara com a coluna ID da tabela de Clientes, tornando-a uma subconsulta correlacionada.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Junções de Tabela com múltiplas condições&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Em alguns casos, pode ser necessário realizar uma junção entre tabelas com base em múltiplas condições, além de uma condição de igualdade. Isso pode ser alcançado utilizando a cláusula AND para combinar múltiplas condições de junção.&lt;/p&gt;

&lt;p&gt;Exemplo de Junção com Múltiplas Condições:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;Funcionarios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Nome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Departamentos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Nome&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;NomeDepartamento&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;Funcionarios&lt;/span&gt;
&lt;span class="k"&gt;INNER&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;Departamentos&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;Funcionarios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DepartamentoID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Departamentos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt;
                          &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;Departamentos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Localizacao&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'São Paulo'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neste exemplo, estamos combinando as tabelas de Funcionários e Departamentos com base em duas condições: a coluna DepartamentoID na tabela de Funcionários deve ser igual à coluna ID na tabela de Departamentos e o valor da coluna Localizacao na tabela de Departamentos deve ser 'São Paulo'.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Join com Operador LIKE&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;O operador LIKE é usado para comparar um valor a um padrão de texto usando caracteres curinga. Pode ser útil em junções para realizar correspondências parciais entre colunas de texto.&lt;/p&gt;

&lt;p&gt;Exemplo de Join com Operador LIKE:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;Funcionarios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Nome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Departamentos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Nome&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;NomeDepartamento&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;Funcionarios&lt;/span&gt;
&lt;span class="k"&gt;INNER&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;Departamentos&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;Funcionarios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DepartamentoID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Departamentos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt;
                          &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;Departamentos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Nome&lt;/span&gt; &lt;span class="k"&gt;LIKE&lt;/span&gt; &lt;span class="s1"&gt;'TI%'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neste exemplo, estamos combinando as tabelas de Funcionários e Departamentos com base em uma condição de igualdade na coluna DepartamentoID e também usando o operador LIKE para garantir que apenas os departamentos com nomes começando com 'TI' sejam incluídos na junção.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Junções Externas (Outer Joins)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Até agora, discutimos principalmente junções internas, onde apenas os registros que possuem correspondência em ambas as tabelas são retornados. No entanto, às vezes é necessário incluir registros de uma tabela mesmo que não haja correspondência na outra tabela. As junções externas, ou outer joins, permitem isso.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;LEFT OUTER JOIN&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;O LEFT OUTER JOIN retorna todos os registros da tabela à esquerda da junção e os registros correspondentes da tabela à direita da junção. Se não houver correspondência, os valores NULL são retornados para as colunas da tabela à direita.&lt;/p&gt;

&lt;p&gt;Exemplo de LEFT OUTER JOIN:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;Funcionarios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Nome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Departamentos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Nome&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;NomeDepartamento&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;Funcionarios&lt;/span&gt;
&lt;span class="k"&gt;LEFT&lt;/span&gt; &lt;span class="k"&gt;OUTER&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;Departamentos&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;Funcionarios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DepartamentoID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Departamentos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neste exemplo, todos os funcionários serão retornados, mesmo que não estejam associados a um departamento. Se um funcionário não estiver associado a um departamento, o valor "NULL" será exibido na coluna "NomeDepartamento".&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;RIGHT OUTER JOIN&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;O RIGHT OUTER JOIN é o oposto do LEFT OUTER JOIN. Ele retorna todos os registros da tabela à direita da junção e os registros correspondentes da tabela à esquerda da junção. Se não houver correspondência, os valores NULL são retornados para as colunas da tabela à esquerda.&lt;/p&gt;

&lt;p&gt;Exemplo de RIGHT OUTER JOIN:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;Funcionarios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Nome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Departamentos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Nome&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;NomeDepartamento&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;Funcionarios&lt;/span&gt;
&lt;span class="k"&gt;RIGHT&lt;/span&gt; &lt;span class="k"&gt;OUTER&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;Departamentos&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;Funcionarios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DepartamentoID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Departamentos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neste exemplo, todos os departamentos serão retornados, mesmo que não tenham funcionários associados a eles. Se um departamento não tiver funcionários associados, o valor "NULL" será exibido na coluna "Nome".&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;FULL OUTER JOIN&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;O FULL OUTER JOIN retorna todos os registros quando houver uma correspondência em uma das tabelas. Ele combina os resultados do LEFT OUTER JOIN e RIGHT OUTER JOIN. Se não houver correspondência, os valores NULL serão retornados para as colunas da tabela sem correspondência.&lt;/p&gt;

&lt;p&gt;Exemplo de FULL OUTER JOIN:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;Funcionarios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Nome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Departamentos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Nome&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;NomeDepartamento&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;Funcionarios&lt;/span&gt;
&lt;span class="k"&gt;FULL&lt;/span&gt; &lt;span class="k"&gt;OUTER&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;Departamentos&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;Funcionarios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DepartamentoID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Departamentos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neste exemplo, todos os funcionários e todos os departamentos serão retornados, combinando os resultados do LEFT e RIGHT OUTER JOIN. Se um funcionário não estiver associado a um departamento ou vice-versa, o valor "NULL" será exibido na coluna correspondente.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;ACID&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;ACID é um acrônimo para Atomicidade, Consistência, Isolamento e Durabilidade, um conjunto de propriedades que garantem a consistência e integridade dos dados em transações.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Atomicidade&lt;/strong&gt;: Garante que todas as operações de uma transação sejam concluídas com sucesso ou revertidas se ocorrer algum erro.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consistência&lt;/strong&gt;: Garante que o banco de dados permaneça em um estado consistente antes e depois de uma transação.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Isolamento&lt;/strong&gt;: Garante que as transações concorrentes não interfiram umas com as outras.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Durabilidade&lt;/strong&gt;: Garante que as alterações feitas por uma transação sejam permanentes, mesmo em caso de falha do sistema.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Aplicação do ACID na Prática
&lt;/h3&gt;

&lt;p&gt;Para ilustrar como o ACID é aplicado na prática, considere o seguinte cenário de um sistema bancário onde um cliente realiza uma transferência de fundos entre duas contas:&lt;/p&gt;

&lt;h3&gt;
  
  
  Atomicidade:
&lt;/h3&gt;

&lt;p&gt;Suponha que uma transação de transferência de fundos envolva duas etapas: debitar o valor da conta de origem e creditar o valor na conta de destino. Se qualquer uma dessas etapas falhar, a transação inteira deve ser revertida para manter a integridade dos dados.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;BEGIN&lt;/span&gt; &lt;span class="n"&gt;TRANSACTION&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;Conta&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;Saldo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Saldo&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;NumeroConta&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'123'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;-- Etapa 1: Débito&lt;/span&gt;
&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;Conta&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;Saldo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Saldo&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;NumeroConta&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'456'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;-- Etapa 2: Crédito&lt;/span&gt;

&lt;span class="k"&gt;COMMIT&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;-- Confirma as alterações se ambas as etapas forem bem-sucedidas, caso contrário, será feito um ROLLBACK&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se ocorrer um erro durante a execução de qualquer uma das etapas, como uma falha de rede ou um problema de integridade de dados, a transação inteira será revertida, garantindo que o saldo das contas permaneça consistente.&lt;/p&gt;

&lt;h3&gt;
  
  
  Consistência:
&lt;/h3&gt;

&lt;p&gt;Antes e depois de uma transação, o banco de dados deve permanecer em um estado consistente. Por exemplo, após uma transferência de fundos, a soma total dos saldos de todas as contas deve permanecer a mesma.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Verifica a consistência antes da transação&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Saldo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;Conta&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Executa a transação de transferência de fundos&lt;/span&gt;

&lt;span class="c1"&gt;-- Verifica a consistência após a transação&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Saldo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;Conta&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se a soma dos saldos antes e depois da transação não for a mesma, isso indicaria uma falha na consistência dos dados.&lt;/p&gt;

&lt;h3&gt;
  
  
  Isolamento:
&lt;/h3&gt;

&lt;p&gt;O isolamento garante que as transações concorrentes não interfiram umas com as outras. Por exemplo, se duas transferências forem realizadas simultaneamente entre as mesmas contas, o saldo correto deve ser refletido em ambas as transações.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Transação 1: Transferência de 50 unidades&lt;/span&gt;
&lt;span class="k"&gt;BEGIN&lt;/span&gt; &lt;span class="n"&gt;TRANSACTION&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;Conta&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;Saldo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Saldo&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;NumeroConta&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'123'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;Conta&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;Saldo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Saldo&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;NumeroConta&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'456'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;COMMIT&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Transação 2: Transferência de 30 unidades (iniciada após a Transação 1)&lt;/span&gt;
&lt;span class="k"&gt;BEGIN&lt;/span&gt; &lt;span class="n"&gt;TRANSACTION&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;Conta&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;Saldo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Saldo&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;NumeroConta&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'123'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;Conta&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;Saldo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Saldo&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;NumeroConta&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'456'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;COMMIT&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Mesmo que a Transação 2 tenha sido iniciada após a Transação 1, o isolamento garante que ambas as transações sejam executadas corretamente, sem interferência mútua.&lt;/p&gt;

&lt;h3&gt;
  
  
  Durabilidade:
&lt;/h3&gt;

&lt;p&gt;A durabilidade garante que as alterações feitas por uma transação sejam permanentes, mesmo em caso de falha do sistema. Isso é geralmente alcançado por meio de técnicas de registro de transações e recuperação.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Após a confirmação da transação&lt;/span&gt;
&lt;span class="k"&gt;COMMIT&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Mesmo em caso de falha do sistema, as alterações feitas pela transação serão duráveis e persistirão no banco de dados&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Mesmo que ocorra uma falha do sistema logo após a confirmação da transação, as alterações feitas por ela serão registradas de forma durável e permanecerão no banco de dados após a recuperação do sistema.&lt;/p&gt;

&lt;p&gt;Em resumo, a aplicação correta dos princípios do ACID garante que as transações sejam confiáveis, consistentes e duráveis, mesmo em ambientes de banco de dados complexos e de alta concorrência.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Stored Procedures e Triggers&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Stored Procedures são conjuntos de instruções SQL que são armazenados no banco de dados e podem ser chamados e executados quando necessário. Triggers são procedimentos automáticos que são executados em resposta a eventos específicos no banco de dados.&lt;/p&gt;

&lt;p&gt;Exemplo de criação de um procedimento armazenado e um gatilho:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;PROCEDURE&lt;/span&gt; &lt;span class="n"&gt;CalcularImposto&lt;/span&gt;
&lt;span class="k"&gt;AS&lt;/span&gt;
&lt;span class="k"&gt;BEGIN&lt;/span&gt;
    &lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;Funcionarios&lt;/span&gt;
    &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;Salario&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Salario&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;85&lt;/span&gt;
    &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;Salario&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;50000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TRIGGER&lt;/span&gt; &lt;span class="n"&gt;AtualizarSalario&lt;/span&gt;
&lt;span class="k"&gt;AFTER&lt;/span&gt; &lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="k"&gt;OF&lt;/span&gt; &lt;span class="n"&gt;Salario&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;Funcionarios&lt;/span&gt;
&lt;span class="k"&gt;BEGIN&lt;/span&gt;
    &lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;RegistroAlteracoes&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FuncionarioID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DataAlteracao&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;VALUES&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;NEW&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;CURRENT_TIMESTAMP&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Indexação&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A indexação é uma técnica usada para otimizar o desempenho das consultas, permitindo que o banco de dados encontre dados mais rapidamente. Os índices são criados em colunas específicas de uma tabela e são usados para localizar registros com base nos valores nessas colunas.&lt;/p&gt;

&lt;p&gt;Exemplo de criação de um índice:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="n"&gt;idx_nome&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;Funcionarios&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Nome&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Transações&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;As transações no SQL são usadas para garantir a consistência dos dados, permitindo que um conjunto de operações seja tratado como uma única unidade de trabalho. As transações garantem que todas as operações sejam concluídas com sucesso ou revertidas se ocorrer algum erro.&lt;/p&gt;

&lt;p&gt;Exemplo de uso de transação:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;
&lt;span class="k"&gt;BEGIN&lt;/span&gt; &lt;span class="n"&gt;TRANSACTION&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;ContaBancaria&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;Saldo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Saldo&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;ID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;ContaBancaria&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;Saldo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Saldo&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;ID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;456&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;COMMIT&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Subconsultas&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Subconsultas, ou consultas aninhadas, são consultas que são incorporadas em outras consultas. Elas podem ser usadas em cláusulas WHERE, FROM, HAVING e SELECT para filtrar ou manipular dados com base em resultados de outras consultas.&lt;/p&gt;

&lt;p&gt;Exemplo de subconsulta:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;Nome&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;Funcionarios&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;DepartamentoID&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;ID&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;Departamentos&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;Nome&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'TI'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Funções de Agregação&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;As funções de agregação são usadas para realizar cálculos em conjuntos de dados, como média, soma, mínimo e máximo. Elas são frequentemente usadas em conjunto com a cláusula GROUP BY para calcular valores agregados para grupos de dados.&lt;/p&gt;

&lt;p&gt;Exemplo de uso de funções de agregação:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;DepartamentoID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;TotalFuncionarios&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;Funcionarios&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;DepartamentoID&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Índices Compostos&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Índices compostos são índices que são criados em mais de uma coluna de uma tabela. Eles são úteis quando você precisa buscar dados com base em múltiplas colunas.&lt;/p&gt;

&lt;p&gt;Exemplo de criação de um índice composto:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="n"&gt;idx_nome_departamento&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;Funcionarios&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Nome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DepartamentoID&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Funções Escalares e Tabela-Valor&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Além das funções de agregação, o SQL suporta funções escalares, que operam em uma única linha de dados, e funções de tabela-valor, que retornam um conjunto de linhas.&lt;/p&gt;

&lt;p&gt;Exemplo de uma função escalar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;FUNCTION&lt;/span&gt; &lt;span class="n"&gt;CalculaIdade&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;DataNascimento&lt;/span&gt; &lt;span class="nb"&gt;DATE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;RETURNS&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt;
&lt;span class="k"&gt;AS&lt;/span&gt;
&lt;span class="k"&gt;BEGIN&lt;/span&gt;
    &lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="n"&gt;DATEDIFF&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;YEAR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;DataNascimento&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;GETDATE&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Janelas (Window Functions)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;As funções de janelas permitem calcular valores com base em um conjunto de linhas relacionadas a uma linha específica. Elas são úteis para cálculos que envolvem comparação com outras linhas na mesma consulta.&lt;/p&gt;

&lt;p&gt;Exemplo de uso de uma função de janela:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;Nome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Salario&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="k"&gt;AVG&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Salario&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;OVER&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;PARTITION&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;DepartamentoID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;MediaSalarioDepartamento&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;Funcionarios&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Uso de Views&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;As views são consultas predefinidas armazenadas no banco de dados. Elas podem ser usadas para simplificar consultas complexas e fornecer uma camada de abstração sobre os dados subjacentes.&lt;/p&gt;

&lt;p&gt;Exemplo de criação de uma view:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;VIEW&lt;/span&gt; &lt;span class="n"&gt;vw_FuncionariosPorDepartamento&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;DepartamentoID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;TotalFuncionarios&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;Funcionarios&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;DepartamentoID&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Controle de Acesso com Funções e Papéis&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;O SQL oferece recursos para controlar o acesso aos dados através de funções e papéis. Funções podem ser usadas para agrupar permissões e atribuí-las a usuários ou papéis, facilitando a gestão de privilégios.&lt;/p&gt;

&lt;p&gt;Exemplo de criação de uma função e atribuição de permissões:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;ROLE&lt;/span&gt; &lt;span class="n"&gt;GerenteDepartamento&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;GRANT&lt;/span&gt; &lt;span class="k"&gt;SELECT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;INSERT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;UPDATE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;DELETE&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;Funcionarios&lt;/span&gt; &lt;span class="k"&gt;TO&lt;/span&gt; &lt;span class="n"&gt;GerenteDepartamento&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Recursos Avançados de Segurança&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Além do controle de acesso básico, o SQL oferece recursos avançados de segurança, como criptografia de dados, auditoria e máscaras de dados sensíveis para proteger informações confidenciais.&lt;/p&gt;

&lt;p&gt;Exemplo de criptografia de dados:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;SYMMETRIC&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt; &lt;span class="n"&gt;MinhaChave&lt;/span&gt;
&lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="n"&gt;ALGORITHM&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;AES_256&lt;/span&gt;
&lt;span class="n"&gt;ENCRYPTION&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;PASSWORD&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Senha123'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Otimização de Consultas&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;A otimização de consultas é crucial para garantir um desempenho eficiente do banco de dados. Isso envolve o uso de índices adequados, estatísticas de otimização, planos de execução e outras técnicas para melhorar a velocidade e eficiência das consultas.&lt;/p&gt;

&lt;p&gt;Exemplo de análise de plano de execução:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;SHOWPLAN_ALL&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;GO&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;Nome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Salario&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;Funcionarios&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;Salario&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;50000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Uso de Triggers para Auditoria&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Além de automatizar tarefas, os gatilhos (triggers) podem ser usados para implementar a auditoria de dados, registrando alterações em tabelas específicas para fins de rastreamento e conformidade.&lt;/p&gt;

&lt;p&gt;Exemplo de gatilho para auditoria:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TRIGGER&lt;/span&gt; &lt;span class="n"&gt;AuditFuncionarios&lt;/span&gt;
&lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;Funcionarios&lt;/span&gt;
&lt;span class="k"&gt;AFTER&lt;/span&gt; &lt;span class="k"&gt;INSERT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;UPDATE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;DELETE&lt;/span&gt;
&lt;span class="k"&gt;AS&lt;/span&gt;
&lt;span class="k"&gt;BEGIN&lt;/span&gt;
    &lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;AuditoriaFuncionarios&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Operacao&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DataHora&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Usuario&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;VALUES&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'INSERT'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;GETDATE&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="k"&gt;SYSTEM_USER&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Replicação de Dados&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;A replicação de dados é um recurso avançado que permite manter cópias consistentes de dados em diferentes servidores para fins de disponibilidade, recuperação de desastres e escalabilidade.&lt;/p&gt;

&lt;p&gt;Exemplo de configuração de replicação:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;
&lt;span class="k"&gt;EXEC&lt;/span&gt; &lt;span class="n"&gt;sp_addpublication&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;publication&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'MinhaPublicacao'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'active'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Gerenciamento de Transações Distribuídas&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Em ambientes distribuídos, o SQL oferece recursos para gerenciar transações distribuídas, garantindo a consistência dos dados em várias fontes de dados.&lt;/p&gt;

&lt;p&gt;Exemplo de transação distribuída:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;
&lt;span class="k"&gt;BEGIN&lt;/span&gt; &lt;span class="n"&gt;DISTRIBUTED&lt;/span&gt; &lt;span class="n"&gt;TRANSACTION&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;-- Executar operações em diferentes fontes de dados aqui&lt;/span&gt;
&lt;span class="k"&gt;COMMIT&lt;/span&gt; &lt;span class="n"&gt;DISTRIBUTED&lt;/span&gt; &lt;span class="n"&gt;TRANSACTION&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Conclusão&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Dominar os princípios do SQL é essencial para qualquer pessoa que trabalhe com bancos de dados relacionais. Este artigo forneceu uma introdução abrangente aos conceitos fundamentais e avançados do SQL, desde a estrutura básica até tópicos mais complexos como transações e procedimentos armazenados. Com este conhecimento, você estará bem equipado para criar, manipular e consultar dados de forma eficaz em qualquer banco de dados relacional.&lt;/p&gt;

</description>
      <category>sql</category>
      <category>braziliandevs</category>
      <category>dotnet</category>
      <category>mysql</category>
    </item>
    <item>
      <title>Dominando a Orientação a Objetos em C#: Conceitos Fundamentais e Prática</title>
      <dc:creator>Bruno Pizol Camargo</dc:creator>
      <pubDate>Thu, 09 May 2024 13:19:44 +0000</pubDate>
      <link>https://dev.to/brunopizol/dominando-a-orientacao-a-objetos-em-c-conceitos-fundamentais-e-pratica-p28</link>
      <guid>https://dev.to/brunopizol/dominando-a-orientacao-a-objetos-em-c-conceitos-fundamentais-e-pratica-p28</guid>
      <description>&lt;h3&gt;
  
  
  Introdução à Orientação a Objetos
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;O que é Orientação a Objetos?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A Orientação a Objetos (OO) é um paradigma de programação que se baseia na ideia de "objetos", que são instâncias de classes. Ela se concentra na organização do código em torno de objetos que possuem dados (atributos) e comportamentos (métodos). C# é uma linguagem fortemente orientada a objetos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Paralelo com Structs em C#&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Em C#, você também pode usar structs, que são tipos de valor semelhantes às classes, mas a principal diferença é que as structs são alocadas na stack, enquanto as instâncias de classes são alocadas no heap. Classes são mais flexíveis e suportam recursos avançados de OO, como herança e polimorfismo, enquanto structs são mais eficientes em termos de memória.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Stack (Pilha):&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;A área de memória chamada "stack" é uma região de memória de tamanho fixo que é usada para armazenar dados temporários, como variáveis locais de funções e informações de chamada de função.&lt;/li&gt;
&lt;li&gt;A alocação de memória na stack é relativamente rápida, uma vez que envolve apenas o deslocamento de um ponteiro de pilha.&lt;/li&gt;
&lt;li&gt;Os dados alocados na stack são automaticamente liberados quando a função que os criou sai de escopo, o que é conhecido como "desalocação automática".&lt;/li&gt;
&lt;li&gt;No contexto da frase, as structs são alocadas na stack, o que significa que quando uma struct é criada, sua memória é reservada na stack, e quando a função que a criou termina sua execução, a memória é automaticamente liberada.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Heap (Monte):&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;A área de memória chamada "heap" é uma região de memória de tamanho variável que é usada para alocar dados de forma dinâmica, como objetos de classe ou estruturas de dados mais complexas.&lt;/li&gt;
&lt;li&gt;A alocação de memória no heap envolve um processo mais complexo, já que o programador deve gerenciar manualmente a alocação e desalocação de memória.&lt;/li&gt;
&lt;li&gt;Os dados alocados no heap não são automaticamente liberados quando não são mais necessários; é responsabilidade do programador liberar essa memória quando terminar de usá-la para evitar vazamentos de memória.&lt;/li&gt;
&lt;li&gt;No contexto da frase, as instâncias de classes são alocadas no heap, o que significa que, quando você cria um objeto de classe, sua memória é reservada no heap, e é sua responsabilidade liberar essa memória quando não for mais necessária.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Exemplo de Struct em C:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="c1"&gt;// Definição de uma struct em C&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Pessoa&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;idade&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Criando uma instância da struct Pessoa&lt;/span&gt;
    &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Pessoa&lt;/span&gt; &lt;span class="n"&gt;pessoa1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Inicializando os campos da struct&lt;/span&gt;
    &lt;span class="n"&gt;strcpy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pessoa1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"João"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;pessoa1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;idade&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Acessando e exibindo os campos da struct&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Nome: %s&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s"&gt;n"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pessoa1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Idade: %d anos&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s"&gt;n"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pessoa1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;idade&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neste exemplo, estamos usando uma struct chamada &lt;code&gt;Pessoa&lt;/code&gt; para armazenar informações sobre uma pessoa, como nome e idade.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exemplo de Classe em C#:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Aqui está como essa mesma estrutura poderia ser representada como uma classe em C#:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Definição de uma classe em C#&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Pessoa&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Campos (ou propriedades) da classe&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Nome&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Idade&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Construtor da classe&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Pessoa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;idade&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Nome&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;Idade&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;idade&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Método para exibir informações da pessoa&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ExibirInformacoes&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Nome: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Nome&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Idade: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Idade&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; anos"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Criando uma instância da classe Pessoa&lt;/span&gt;
        &lt;span class="n"&gt;Pessoa&lt;/span&gt; &lt;span class="n"&gt;pessoa1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Pessoa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"João"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;30&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Acessando e exibindo informações da pessoa&lt;/span&gt;
        &lt;span class="n"&gt;pessoa1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ExibirInformacoes&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neste exemplo em C#, definimos uma classe chamada &lt;code&gt;Pessoa&lt;/code&gt; com campos (ou propriedades) para armazenar informações e um construtor para inicializar esses campos. Além disso, há um método &lt;code&gt;ExibirInformacoes&lt;/code&gt; que exibe os detalhes da pessoa.&lt;/p&gt;

&lt;h3&gt;
  
  
  Classes e Métodos
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Classes:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Imagine uma "receita de biscoito" como uma classe. A classe é uma espécie de modelo ou plano que define como criar biscoitos. Ele contém informações sobre os ingredientes (atributos) e as etapas necessárias para fazer os biscoitos (métodos).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Atributos:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Os atributos são como os ingredientes da receita de biscoito. Por exemplo, a quantidade de farinha, açúcar, ovos e chocolate. Esses ingredientes são os atributos da classe. Cada biscoito (objeto) que você faz usando essa receita terá seus próprios valores específicos para esses ingredientes.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Métodos:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Os métodos são como as etapas da receita que dizem como preparar a massa, moldar os biscoitos e assá-los. Cada método é uma ação que pode ser executada com base nos atributos da classe. Por exemplo, o método "assar" usa os atributos (ingredientes) para produzir biscoitos cozidos.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Objetos:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Os objetos são como biscoitos individuais que você faz usando a receita. Cada objeto é uma instância da classe (receita). Eles compartilham a mesma estrutura definida pela classe (mesmos ingredientes e etapas), mas cada objeto pode ter seus próprios valores de atributos (quantidades diferentes de ingredientes) e pode ser produzido separadamente.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Herança:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Imagine que você tem diferentes tipos de biscoitos, como biscoitos de chocolate e biscoitos de baunilha. Você pode criar uma nova classe chamada "BiscoitoDeChocolate" que herda as características (atributos e métodos) da classe base "Biscoito". Assim, você reutiliza a estrutura básica da receita e adiciona ingredientes ou etapas específicos para os biscoitos de chocolate.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Classes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As classes são os blocos de construção fundamentais da orientação a objetos em C#. Elas representam tipos de dados e definem a estrutura (atributos) e o comportamento (métodos) dos objetos.&lt;/p&gt;

&lt;p&gt;Exemplo de uma classe simples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Pessoa&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Nome&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Idade&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Apresentar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Meu nome é &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Nome&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; e tenho &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Idade&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; anos."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Métodos&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Métodos são funções dentro de uma classe que realizam ações ou operações relacionadas a objetos dessa classe.&lt;/p&gt;

&lt;p&gt;Exemplo de uso de métodos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;Pessoa&lt;/span&gt; &lt;span class="n"&gt;pessoa&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Pessoa&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;pessoa&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Nome&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"João"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;pessoa&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Idade&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;30&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;pessoa&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Apresentar&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Saída: "Meu nome é João e tenho 30 anos."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Instanciar Objetos
&lt;/h3&gt;

&lt;p&gt;Para usar uma classe e criar objetos, você precisa instanciá-la. Isso envolve a alocação de memória e a inicialização dos atributos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;Pessoa&lt;/span&gt; &lt;span class="n"&gt;pessoa&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Pessoa&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aqui, &lt;code&gt;pessoa&lt;/code&gt; é uma instância da classe &lt;code&gt;Pessoa&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Garbage Collector
&lt;/h3&gt;

&lt;p&gt;O Garbage Collector (coletor de lixo) em C# é responsável por liberar a memória alocada para objetos que não são mais referenciados, tornando-os elegíveis para coleta.&lt;/p&gt;

&lt;p&gt;Você não precisa se preocupar em liberar a memória manualmente, pois o Garbage Collector faz isso automaticamente.&lt;/p&gt;

&lt;h3&gt;
  
  
  Copiar Objetos Instanciados
&lt;/h3&gt;

&lt;p&gt;Em C#, quando você atribui uma variável de objeto a outra, na verdade está criando uma referência compartilhada para o mesmo objeto, não uma cópia real. Para criar uma cópia independente, você pode implementar o método &lt;code&gt;Clone()&lt;/code&gt; ou criar uma nova instância e copiar os valores manualmente.&lt;/p&gt;

&lt;h3&gt;
  
  
  Herança
&lt;/h3&gt;

&lt;p&gt;A herança permite que uma classe herde atributos e métodos de outra classe, estabelecendo uma relação "é um" entre as classes.&lt;/p&gt;

&lt;p&gt;Exemplo de herança:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Aluno&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Pessoa&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Matricula&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neste caso, a classe &lt;code&gt;Aluno&lt;/code&gt; herda todos os atributos e métodos da classe &lt;code&gt;Pessoa&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Implementação e Extensão
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Implementação&lt;/strong&gt;: Interfaces em C# permitem definir contratos que as classes devem seguir. Uma classe pode implementar várias interfaces, garantindo que ela forneça determinados métodos e propriedades.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;IReprodutivel&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Reproduzir&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Gato&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IReprodutivel&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Reproduzir&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"O gato está se reproduzindo."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Extensão&lt;/strong&gt;: Você pode estender classes existentes sem modificá-las usando métodos de extensão. Isso é útil para adicionar funcionalidades sem alterar o código fonte original.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StringExtensions&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="err"&gt;É&lt;/span&gt;&lt;span class="nf"&gt;NuloOuVazio&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;texto&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsNullOrEmpty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;texto&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Prós e Contras da Orientação a Objetos em C
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Prós:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Encapsulamento: Ajuda a proteger dados sensíveis.&lt;/li&gt;
&lt;li&gt;Reutilização de Código: Classes e herança permitem reutilização de código.&lt;/li&gt;
&lt;li&gt;Manutenção: Facilita a manutenção do código.&lt;/li&gt;
&lt;li&gt;Abstração: Permite representar conceitos do mundo real.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Contras:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Complexidade: Pode resultar em código complexo se não for bem projetado.&lt;/li&gt;
&lt;li&gt;Desempenho: Pode ser menos eficiente do que abordagens mais simples em alguns casos.&lt;/li&gt;
&lt;li&gt;Curva de Aprendizado: Pode ser desafiador para iniciantes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A orientação a objetos é uma parte fundamental do desenvolvimento em C# e é amplamente usada na construção de aplicativos modernos. É importante entender os conceitos e práticas de OO para tirar o máximo proveito dessa linguagem.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exercícios:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Crie uma classe chamada &lt;code&gt;Círculo&lt;/code&gt; que represente um círculo e inclua métodos para calcular a área e o perímetro.&lt;/li&gt;
&lt;li&gt;Implemente uma classe &lt;code&gt;ContaBancária&lt;/code&gt; com métodos para depósito, saque e exibição do saldo atual.&lt;/li&gt;
&lt;li&gt;Crie uma hierarquia de classes para representar diferentes tipos de veículos, como carro, bicicleta e caminhão, com métodos para acelerar, desacelerar e parar.&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;Como gostaria de proceder?&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>dotnet</category>
      <category>braziliandevs</category>
      <category>oop</category>
    </item>
    <item>
      <title>Introdução às APIs, REST e SOAP: Compreendendo os Pilares do Desenvolvimento Web Moderno</title>
      <dc:creator>Bruno Pizol Camargo</dc:creator>
      <pubDate>Wed, 08 May 2024 13:41:06 +0000</pubDate>
      <link>https://dev.to/brunopizol/introducao-as-apis-rest-e-soap-compreendendo-os-pilares-do-desenvolvimento-web-moderno-57li</link>
      <guid>https://dev.to/brunopizol/introducao-as-apis-rest-e-soap-compreendendo-os-pilares-do-desenvolvimento-web-moderno-57li</guid>
      <description>&lt;p&gt;No amplo campo do desenvolvimento web, um termo que frequentemente surge é "API". Mas o que exatamente é uma API e como ela funciona dentro do panorama mais amplo das tecnologias web? Além disso, o que distingue duas das arquiteturas de API mais prevalentes, REST e SOAP? Este artigo visa desmistificar esses conceitos, fornecendo uma visão abrangente para iniciantes enquanto lança luz sobre suas aplicações práticas em ambientes de desenvolvimento modernos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Revelando o Framework .NET: Uma Breve Jornada pela História
&lt;/h2&gt;

&lt;p&gt;Antes de adentrarmos nas complexidades das APIs, vamos primeiro introduzir o alicerce de muitas aplicações web contemporâneas: o framework .NET. Nascido em 2002 como uma plataforma proprietária exclusivamente dedicada a ambientes Windows, o .NET emergiu como um robusto kit de desenvolvimento de software (SDK) para a construção de uma variedade de aplicações. Sua versatilidade logo se tornou evidente ao evoluir para suportar o desenvolvimento multiplataforma, incluindo aplicações móveis através do Xamarin, soluções web por meio do ASP.NET e Blazor, e compatibilidade com sistemas Windows e Linux.&lt;/p&gt;

&lt;p&gt;Similar ao Java em muitos aspectos, o .NET ostenta um ambiente amigável ao usuário, especialmente acolhedor para iniciantes no campo da programação. Assim como o Java abstrai os detalhes específicos do hardware por meio da Java Virtual Machine (JVM), o .NET permite que os desenvolvedores escrevam código visando o Common Language Runtime (CLR), transcendendo as limitações da codificação específica do dispositivo.&lt;/p&gt;

&lt;p&gt;A jornada do .NET não parou em sua concepção. Em 2014, com o advento do .NET Core, a Microsoft adotou uma abordagem mais inclusiva, estendendo seu suporte além dos limites do Windows para incluir Linux e macOS. Avançando para 2020, a nomenclatura "Core" foi abandonada, consolidando sua identidade sob o estandarte do .NET 5, agora totalmente de código aberto e impulsionado pela comunidade.&lt;/p&gt;

&lt;h2&gt;
  
  
  Explorando o Panorama das APIs
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Compreendendo APIs
&lt;/h3&gt;

&lt;p&gt;Em seu cerne, uma Interface de Programação de Aplicativos (API) serve como uma ponte entre diferentes aplicações de software, permitindo que elas se comuniquem e interajam entre si de forma transparente. As APIs definem os métodos e protocolos pelos quais sistemas diversos podem solicitar e trocar dados, capacitando os desenvolvedores a aproveitar funcionalidades de serviços existentes sem reinventar a roda.&lt;/p&gt;

&lt;h3&gt;
  
  
  JSON vs. XML
&lt;/h3&gt;

&lt;p&gt;Quando se trata de formatos de intercâmbio de dados, dois padrões predominantes surgem: JSON (JavaScript Object Notation) e XML (eXtensible Markup Language). JSON, conhecido por sua sintaxe leve e legível por humanos, tornou-se ubíquo no desenvolvimento web moderno, oferecendo simplicidade e facilidade de análise. Por outro lado, XML, com sua estrutura hierárquica e amplo suporte de ferramentas, continua a encontrar utilidade em certos domínios, especialmente onde a validação e transformação de documentos são primordiais.&lt;/p&gt;

&lt;p&gt;Exemplo: Considere a representação de um usuário em JSON e XML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;JSON&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"John Doe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"john@example.com"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;XML&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;&amp;lt;user&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;id&amp;gt;&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="err"&gt;&amp;lt;/id&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;name&amp;gt;John&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Doe&amp;lt;/name&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;email&amp;gt;john@example.com&amp;lt;/email&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;&amp;lt;/user&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  SOAP (Simple Object Access Protocol)
&lt;/h3&gt;

&lt;p&gt;SOAP representa um dos protocolos mais antigos e estabelecidos para a construção de APIs. Caracterizado por sua estrita conformidade com padrões e conjunto abrangente de recursos, o SOAP facilita a troca de informações estruturadas de maneira independente de plataforma. Apesar de sua robustez, a verbosidade e complexidade do SOAP levaram ao surgimento de alternativas mais leves, como o REST.&lt;/p&gt;

&lt;h3&gt;
  
  
  GraphQL
&lt;/h3&gt;

&lt;p&gt;Em contraste com a estrutura rígida do SOAP, o GraphQL introduz uma mudança de paradigma no design de APIs, priorizando flexibilidade e eficiência. Desenvolvido pelo Facebook, o GraphQL capacita os clientes a consultar precisamente os dados de que necessitam, minimizando assim a sobrecarga e a subcarga de informações. Ao permitir a busca declarativa de dados e fornecer um esquema fortemente tipado, o GraphQL promove uma experiência de desenvolvimento mais intuitiva e simplificada.&lt;/p&gt;

&lt;p&gt;Exemplo: Suponha que temos uma API GraphQL para consultar informações de usuários e seus posts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;posts&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Decifrando REST e SOAP: Uma Análise Comparativa
&lt;/h2&gt;

&lt;h3&gt;
  
  
  REST (Representational State Transfer)
&lt;/h3&gt;

&lt;p&gt;Reconhecido por sua simplicidade e aderência aos princípios da web, o REST emergiu como o padrão de facto para projetar APIs web. Ao abraçar a ausência de estado do HTTP, as APIs RESTful alavancam identificadores uniformes de recursos (URIs) e métodos HTTP padrão (GET, POST, PUT, DELETE) para facilitar a manipulação de recursos. Ao promover o desacoplamento entre clientes e servidores e abraçar o hipermedia como o mecanismo de estado da aplicação (HATEOAS), o REST possibilita escalabilidade, confiabilidade e interoperabilidade entre sistemas diversos.&lt;/p&gt;

&lt;h3&gt;
  
  
  SOAP vs. REST: Escolhendo a Solução Adequada
&lt;/h3&gt;

&lt;p&gt;Embora tanto o SOAP quanto o REST cumpram o objetivo fundamental de permitir a comunicação entre componentes de software, suas disparidades arquiteturais exigem uma consideração cuidadosa. O SOAP, com seus contratos formais e recursos de segurança integrados, se destaca em cenários que exigem integridade transacional e confiabilidade em nível de protocolo. Por outro lado, a natureza leve e o design intuitivo do REST o tornam adequado para arquiteturas orientadas a recursos, especialmente no contexto de aplicações baseadas na web e microsserviços.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Em conclusão, as APIs servem como o alicerce do desenvolvimento web moderno, facilitando a integração e interoperabilidade entre sistemas diversos. Seja alavancando a robustez do SOAP ou a simplicidade do REST, os desenvolvedores dispõem de uma ampla gama de ferramentas para arquitetar soluções escaláveis e eficientes, adaptadas às suas necessidades específicas. À medida que o cenário tecnológico continua a evoluir, um entendimento sólido das APIs e de seus princípios subjacentes permanece indispensável para navegar pelas complexidades da engenharia de software contemporânea.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Descomplicando o mundo da programação - Guia basico sobre funcionamento e utilização do kafka em .NET</title>
      <dc:creator>Bruno Pizol Camargo</dc:creator>
      <pubDate>Thu, 14 Mar 2024 19:14:34 +0000</pubDate>
      <link>https://dev.to/brunopizol/descomplicando-o-mundo-da-programacao-guia-basico-sobre-funcionamento-e-utilizacao-do-kafka-em-net-bhe</link>
      <guid>https://dev.to/brunopizol/descomplicando-o-mundo-da-programacao-guia-basico-sobre-funcionamento-e-utilizacao-do-kafka-em-net-bhe</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;Introdução&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;O Apache Kafka é uma plataforma de streaming de dados distribuída, de código aberto, que fornece uma arquitetura para a transmissão eficiente, processamento em tempo real e armazenamento durável de grandes volumes de dados em um ambiente distribuído. Ele é projetado para lidar com fluxos de dados em tempo real, sendo amplamente utilizado para construir sistemas escaláveis e de alta performance em aplicações que demandam processamento de eventos em tempo real.&lt;/p&gt;

&lt;p&gt;O Kafka é como um mega grupo de WhatsApp super organizado, mas em vez de mensagens de texto, é usado para compartilhar informações de todos os tipos! Imagina que você e seus amigos adoram falar sobre vários assuntos, como séries, jogos e curiosidades.&lt;br&gt;
Agora, cada um desses assuntos é como um "canal" no Kafka. As pessoas que adoram séries ficam em um canal, os gamers em outro, e assim por diante. O Kafka ajuda a garantir que todo mundo receba as notícias certinhas, no momento certo, mesmo que muita gente esteja conversando ao mesmo tempo.&lt;br&gt;
É como se fosse um assistente pessoal mega eficiente, mas para manter todos atualizados sobre as coisas legais que estão acontecendo, como os lançamentos das suas séries favoritas ou novidades nos jogos que você curte. É uma forma de organizar e compartilhar informações, mesmo que muita gente esteja participando da conversa! 🌐✨&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqsw40rj82gql8gfzm02u.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqsw40rj82gql8gfzm02u.jpg" alt="Image description" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;O que é Mensageria?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Atualmente o Kafka é empregado principalmente no uso de microserviços como um gerenciador de mensageria, mas o que é mensageria?&lt;/p&gt;

&lt;p&gt;A mensageria é um padrão arquitetural em que sistemas distribuídos se comunicam através do envio de mensagens assíncronas entre componentes. Essas mensagens podem conter informações, comandos ou eventos e são fundamentais para a construção de sistemas resilientes, escaláveis e desacoplados.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv6pf1qaoj5wo4odllrdt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv6pf1qaoj5wo4odllrdt.png" alt="Image description" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Por que Usar Mensageria?&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Desacoplamento:&lt;/strong&gt; Permite que componentes do sistema se comuniquem sem conhecimento direto uns dos outros, reduzindo o acoplamento.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Escalabilidade:&lt;/strong&gt; Facilita a escalabilidade horizontal, permitindo a distribuição de processamento entre diversos serviços.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resiliência:&lt;/strong&gt; Mensagens assíncronas lidam melhor com falhas temporárias, garantindo que a comunicação seja retomada após a recuperação do serviço.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Desvantagens da Mensageria:&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Complexidade:&lt;/strong&gt; Introduz complexidade adicional na arquitetura.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Latência:&lt;/strong&gt; Mensagens assíncronas podem adicionar latência à comunicação entre componentes.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Por que Usar o Kafka?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;O Kafka é escolhido por muitas organizações devido às suas características distintas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Escalabilidade:&lt;/strong&gt; Kafka é altamente escalável, permitindo processar grandes volumes de dados em tempo real.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Durabilidade:&lt;/strong&gt; Mensagens são armazenadas de forma durável e podem ser reprocessadas, garantindo confiabilidade.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Particionamento:&lt;/strong&gt; Tópicos podem ser particionados, distribuindo o processamento entre vários consumidores.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No contexto do Apache Kafka, os conceitos de partition, consumer, topic, broker e offset são fundamentais para entender como o Kafka opera.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Topic (Tópico):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Definição:&lt;/strong&gt; Um tópico no Kafka é uma categoria ou feed de mensagens. Cada mensagem publicada em um tópico é mantida por um período de tempo configurável, independentemente de os consumidores terem ou não lido essa mensagem.&lt;/p&gt;

&lt;p&gt;Pensa nos tópicos como canais de conversa. Cada tópico é como um grupo no WhatsApp, mas ao invés de textos, a galera troca mensagens.&lt;/p&gt;

&lt;p&gt;Os produtores (quem manda as mensagens) jogam suas mensagens nos tópicos, e os consumidores (quem recebe as mensagens) ficam de olho nos tópicos que interessam a eles.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Partition (Partição):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Definição:&lt;/strong&gt; Um tópico pode ser dividido em várias partições. As partições permitem que os dados sejam distribuídos e processados em paralelo.&lt;/p&gt;

&lt;p&gt;Imagina que um tópico é um bolo enorme, e as partições são pedaços desse bolo. Dividir em pedaços ajuda na hora de distribuir para todo mundo.&lt;/p&gt;

&lt;p&gt;Se o tópico é sobre séries, uma partição pode ser só de "Game of Thrones" e outra de "Stranger Things". Cada fã vai direto para a partição que mais gosta.&lt;/p&gt;

&lt;p&gt;As partições possibilitam a escala horizontal e permitem que várias instâncias de consumidores processem mensagens de um tópico simultaneamente.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Consumer (Consumidor):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Definição:&lt;/strong&gt; Um consumidor é uma aplicação ou processo que se inscreve em tópicos do Kafka para consumir mensagens. Cada consumidor mantém um registro do último offset que leu em cada partição.&lt;/p&gt;

&lt;p&gt;Os consumidores são os fãs que querem receber as mensagens. Eles escolhem em quais tópicos querem participar.&lt;/p&gt;

&lt;p&gt;Se você é um consumidor, pode se inscrever no tópico de "Game of Thrones" e receber todas as últimas novidades dessa série.&lt;/p&gt;

&lt;p&gt;Consumidores processam mensagens em tempo real ou de acordo com a lógica de processamento específica do aplicativo.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Offset:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Definição:&lt;/strong&gt; O offset é um identificador único associado a cada mensagem em uma partição. Ele representa a posição de um consumidor em uma partição específica.&lt;/p&gt;

&lt;p&gt;Sabe quando você para de assistir a um episódio no Netflix e quer continuar depois? O offset é tipo o número do episódio onde você parou. Se você já viu até o terceiro episódio de "Stranger Things", o offset vai ser 3. Então, na próxima vez que voltar, sabe exatamente por onde começar.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;O offset permite que os consumidores controlem o andamento do processamento, indicando qual mensagem eles já consumiram. Os consumidores podem reiniciar a partir de um offset específico em caso de falha ou para processar novamente mensagens.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Broker:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;O que é:&lt;/strong&gt; O broker desempenha o papel central na organização do sistema. Funciona como o gestor principal do Kafka, encarregado de administrar tópicos, particionamento e monitoramento das mensagens.
O broker é como o servidor do WhatsApp que garante que suas mensagens cheguem para todos no grupo. Ele também cuida para que, se um consumidor estiver offline, ele receba as mensagens quando voltar.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Fluxo de Dados Básico:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Um produtor publica mensagens em um tópico.&lt;/li&gt;
&lt;li&gt;Cada tópico pode ter várias partições.&lt;/li&gt;
&lt;li&gt;Consumidores se inscrevem em tópicos e podem processar mensagens de partições diferentes em paralelo.&lt;/li&gt;
&lt;li&gt;Cada mensagem em uma partição tem um offset único.&lt;/li&gt;
&lt;li&gt;Consumidores mantêm o controle do último offset consumido para cada partição.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F26wpzjy9d61etghhs1bu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F26wpzjy9d61etghhs1bu.png" alt="Image description" width="800" height="376"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;fonte: &lt;a href="https://developers.redhat.com/blog/2021/05/04/event-driven-apis-and-schema-governance-for-apache-kafka-get-ready-for-kafka-summit-europe-2021"&gt;https://developers.redhat.com/blog/2021/05/04/event-driven-apis-and-schema-governance-for-apache-kafka-get-ready-for-kafka-summit-europe-2021&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Escalabilidade:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A divisão em partições permite a distribuição de carga e paralelismo.&lt;/li&gt;
&lt;li&gt;Consumidores podem ser escalados horizontalmente para processar partições em paralelo.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Durabilidade e Retenção:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;As mensagens em um tópico podem ser mantidas por um período configurável.&lt;/li&gt;
&lt;li&gt;Os consumidores mantêm o controle do offset, permitindo que continuem de onde pararam, mesmo após reinicializações.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Rebalanceamento:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Quando novos consumidores são adicionados ou consumidores existentes são removidos, o Kafka realiza um rebalanceamento para redistribuir as partições entre os consumidores.&lt;/li&gt;
&lt;li&gt;Isso garante um processamento equitativo e eficiente das mensagens.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Mão na massa
&lt;/h2&gt;

&lt;p&gt;Agora que você já sabe todos esses conceitos fundamentais do Kafka para projetar sistemas escaláveis, duráveis e tolerantes a falhas para processamento de eventos em tempo real, vamos botar a mão na massa e fazer uma implementação básica.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Configuração do Ambiente&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Vamos facilitar nossa vida e vamos utilizar uma imagem docker do kafka, para isso vamos configurar um docker-compose para nos ajudar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sc"&gt;'2'&lt;/span&gt;
&lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="n"&gt;zookeeper&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;confluentinc&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;cp&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;zookeeper&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;latest&lt;/span&gt;
    &lt;span class="n"&gt;networks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
      &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;broker&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;kafka&lt;/span&gt;
    &lt;span class="n"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="n"&gt;ZOOKEEPER_CLIENT_PORT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2181&lt;/span&gt;
      &lt;span class="n"&gt;ZOOKEEPER_TICK_TIME&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2000&lt;/span&gt;

  &lt;span class="n"&gt;kafka&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;confluentinc&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;cp&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;kafka&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;latest&lt;/span&gt;
    &lt;span class="n"&gt;networks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
      &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;broker&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;kafka&lt;/span&gt;
    &lt;span class="n"&gt;depends_on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;zookeeper&lt;/span&gt;
    &lt;span class="n"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="m"&gt;9092&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;9092&lt;/span&gt;
      &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="m"&gt;9101&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;9101&lt;/span&gt;
    &lt;span class="n"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="n"&gt;KAFKA_BROKER_ID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
      &lt;span class="n"&gt;KAFKA_ZOOKEEPER_CONNECT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;zookeeper&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;2181&lt;/span&gt;
      &lt;span class="n"&gt;KAFKA_ADVERTISED_LISTENERS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;PLAINTEXT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//kafka:29092,PLAINTEXT_HOST://localhost:9092&lt;/span&gt;
      &lt;span class="n"&gt;KAFKA_LISTENER_SECURITY_PROTOCOL_MAP&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;PLAINTEXT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;PLAINTEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;PLAINTEXT_HOST&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;PLAINTEXT&lt;/span&gt;
      &lt;span class="n"&gt;KAFKA_INTER_BROKER_LISTENER_NAME&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;PLAINTEXT&lt;/span&gt;
      &lt;span class="n"&gt;KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;

  &lt;span class="n"&gt;kafdrop2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;obsidiandynamics&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;kafdrop&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;latest&lt;/span&gt;
    &lt;span class="n"&gt;networks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
      &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;broker&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;kafka&lt;/span&gt;
    &lt;span class="n"&gt;depends_on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;kafka&lt;/span&gt;
    &lt;span class="n"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="m"&gt;19000&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;9000&lt;/span&gt;
    &lt;span class="n"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="n"&gt;KAFKA_BROKERCONNECT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;kafka&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;29092&lt;/span&gt;

  &lt;span class="n"&gt;akhq&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;    
    &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;tchiotludo&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;akhq&lt;/span&gt;
    &lt;span class="n"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="n"&gt;AKHQ_CONFIGURATION&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;
        &lt;span class="n"&gt;akhq&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
          &lt;span class="n"&gt;connections&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;localhost&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
              &lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;bootstrap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;servers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"kafka:29092"&lt;/span&gt;
    &lt;span class="n"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="m"&gt;8082&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;8082&lt;/span&gt;          
  &lt;span class="n"&gt;kafka&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ui&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;provectuslabs&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;kafka&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ui&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;latest&lt;/span&gt;
    &lt;span class="n"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="m"&gt;8080&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;8080&lt;/span&gt;
    &lt;span class="n"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="n"&gt;KAFKA_CLUSTERS_0_NAME&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;local&lt;/span&gt;
      &lt;span class="n"&gt;KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"kafka:29092"&lt;/span&gt;        
    &lt;span class="n"&gt;networks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;broker&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;kafka&lt;/span&gt;
&lt;span class="n"&gt;networks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="n"&gt;broker&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;kafka&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;bridge&lt;/span&gt;  

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Execute o comando abaixo para iniciar os serviços do Kafka e do ZooKeeper:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker-compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Criação de Tópico&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Agora, você precisa criar um tópico para produzir e consumir mensagens. Substitua &lt;strong&gt;&lt;code&gt;meu-topico&lt;/code&gt;&lt;/strong&gt; pelo nome desejado:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; kafka /opt/kafka_2.12-2.8.0/bin/kafka-topics.sh &lt;span class="nt"&gt;--create&lt;/span&gt; &lt;span class="nt"&gt;--topic&lt;/span&gt; meu-topico &lt;span class="nt"&gt;--bootstrap-server&lt;/span&gt; localhost:9092 &lt;span class="nt"&gt;--partitions&lt;/span&gt; 1 &lt;span class="nt"&gt;--replication-factor&lt;/span&gt; 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Configuração no &lt;code&gt;Startup.cs&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.AspNetCore.Builder&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.AspNetCore.Hosting&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Extensions.Configuration&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Extensions.DependencyInjection&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Extensions.Hosting&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;Kafkadotnetexample&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Startup&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Startup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IConfiguration&lt;/span&gt; &lt;span class="n"&gt;configuration&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Configuration&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;configuration&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;IConfiguration&lt;/span&gt; &lt;span class="n"&gt;Configuration&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ConfigureServices&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IServiceCollection&lt;/span&gt; &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Adiciona os serviços necessários&lt;/span&gt;
            &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddSingleton&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;EventProducer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Adiciona o produtor como serviço singleton&lt;/span&gt;
            &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddHostedService&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;EventConsumer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Adiciona o consumidor como serviço hospedado&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Configure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IApplicationBuilder&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IWebHostEnvironment&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Explicação:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;Startup&lt;/code&gt;&lt;/strong&gt; é uma classe que configura o ambiente da aplicação durante a inicialização.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;ConfigureServices&lt;/code&gt;&lt;/strong&gt; é chamado para configurar os serviços que serão usados pela aplicação. Aqui, registramos o produtor e o consumidor como serviços.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;Configure&lt;/code&gt;&lt;/strong&gt; é usado para configurar o pipeline de middleware da aplicação, mas está vazio neste exemplo.&lt;/li&gt;
&lt;li&gt;Um &lt;strong&gt;&lt;code&gt;HostedService&lt;/code&gt;&lt;/strong&gt; é adequado quando você precisa de um serviço que seja executado continuamente em segundo plano, como é o caso de um consumidor de eventos Kafka que precisa estar sempre ativo para consumir mensagens em tempo real.&lt;/li&gt;
&lt;li&gt;Ele é iniciado quando a aplicação é iniciada e é encerrado quando a aplicação é encerrada.&lt;/li&gt;
&lt;li&gt;Se múltiplos consumidores precisam ser executados simultaneamente, cada um deles pode ser registrado como um &lt;strong&gt;&lt;code&gt;HostedService&lt;/code&gt;&lt;/strong&gt; separado.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Produção e consumo de mensagens:&lt;/strong&gt;
&lt;/h3&gt;

&lt;h3&gt;
  
  
  Produtor de Eventos (C#)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Confluent.Kafka&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Extensions.Configuration&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Extensions.Logging&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Collections.Generic&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Threading.Tasks&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MessageProducer&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;IProducer&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_producer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;ILogger&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MessageProducer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_logger&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;EventProducer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IConfiguration&lt;/span&gt; &lt;span class="n"&gt;configuration&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ILogger&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MessageProducer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_logger&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;kafkaConfig&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ProducerConfig&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;configuration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetSection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"KafkaProducer"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;Bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;kafkaConfig&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;_producer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ProducerBuilder&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;kafkaConfig&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;Build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;ProduceMessageAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;kafkaMessage&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Key&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Value&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;deliveryResult&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_producer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ProduceAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;kafkaMessage&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;_logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LogInformation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Mensagem entregue para: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;deliveryResult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TopicPartitionOffset&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;ProduceMessagesInBatchAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;tasks&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;DeliveryResult&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&amp;gt;();&lt;/span&gt;

        &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;kafkaMessage&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;Key&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;Value&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;
            &lt;span class="p"&gt;};&lt;/span&gt;

            &lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_producer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ProduceAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;kafkaMessage&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WhenAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;aqui podemos analisar o código da seguinte forma:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;É feita a injeção de dependência no construtor injetando a interface de log &lt;code&gt;ILogger&lt;/code&gt;, a interface do producer do &lt;em&gt;confluent.kafka&lt;/em&gt; &lt;code&gt;IProducer&lt;/code&gt; e as configurações do kafka com &lt;code&gt;IConfiguration&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Há um método assíncrono &lt;code&gt;ProduceMessageAsync&lt;/code&gt; que produz e envia as mensagens&lt;/li&gt;
&lt;li&gt;há outro método assíncrono &lt;code&gt;ProduceMessagesInBatchAsync&lt;/code&gt; que envia as mensagens em lote.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Consumidor de Eventos (C#)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Confluent.Kafka&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Extensions.Configuration&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Extensions.Hosting&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Extensions.Logging&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Threading&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Threading.Tasks&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MessageConsumer&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;BackgroundService&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;IConsumer&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Ignore&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_consumer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;IProducer&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_deadLetterProducer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;ILogger&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MessageConsumer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_logger&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;EventConsumer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IConfiguration&lt;/span&gt; &lt;span class="n"&gt;configuration&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IProducer&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;deadLetterProducer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ILogger&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MessageConsumer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_logger&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;_deadLetterProducer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;deadLetterProducer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;kafkaConfig&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ConsumerConfig&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;configuration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetSection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"KafkaConsumer"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;Bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;kafkaConfig&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;_consumer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ConsumerBuilder&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Ignore&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;kafkaConfig&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;Build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;ExecuteAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CancellationToken&lt;/span&gt; &lt;span class="n"&gt;stoppingToken&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_consumer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"meu-topico"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;try&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;stoppingToken&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsCancellationRequested&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;consumeResult&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_consumer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Consume&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stoppingToken&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;ProcessAndCommitMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;consumeResult&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
                    &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

                &lt;span class="n"&gt;_logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LogError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Erro ao processar mensagem: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;consumeResult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="nf"&gt;HandleDeadLetter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;consumeResult&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ConsumeException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;_logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LogError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Erro ao consumir: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Reason&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;ProcessAndCommitMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ConsumeResult&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Ignore&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;consumeResult&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;isSuccess&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ProcessMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;consumeResult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isSuccess&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;_logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LogInformation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Mensagem processada com sucesso: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;consumeResult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;_consumer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Commit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;consumeResult&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;isSuccess&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;ProcessMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"result success"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;StringComparison&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OrdinalIgnoreCase&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;HandleDeadLetter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ConsumeResult&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Ignore&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;consumeResult&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;_deadLetterProducer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ProduceAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"meu-topico-dead-letter"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Value&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;consumeResult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
            &lt;span class="n"&gt;_consumer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Commit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;consumeResult&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;_logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LogError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Erro ao encaminhar para dead letter: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aqui podemos analisar o código da seguinte forma:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;É feita a injeção de dependência no construtor injetando a parte da interface de log &lt;code&gt;ILogger&lt;/code&gt;, a interface do consumer &lt;code&gt;IConsumer&lt;/code&gt; e do deadletter producer &lt;code&gt;IProducer&lt;/code&gt; do &lt;em&gt;confluent.kafka&lt;/em&gt; e as configurações do kafka com &lt;code&gt;IConfiguration&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;A classe herda de &lt;code&gt;BackgroundService&lt;/code&gt; que permite ela ser executada em segundo plano.&lt;/li&gt;
&lt;li&gt;o método de consumo &lt;code&gt;ExecuteAsync&lt;/code&gt; onde é verificado o valor da mensagem no método &lt;code&gt;ProcessAndCommitMessage&lt;/code&gt; onde se o valor for &lt;em&gt;success&lt;/em&gt; ele gera a confirmação da mensagem com o commit.&lt;/li&gt;
&lt;li&gt;se o retorno do &lt;code&gt;ProcessAndCommitMessage&lt;/code&gt; for falso ele encaminha a mensagem para o topico da  deadletter e confirma a mensagem original para não ser reenviada.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Resumindo:
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Produtor de Eventos (&lt;code&gt;MessageProducer&lt;/code&gt;):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;O que faz?&lt;/strong&gt; Envio de mensagens para o Kafka.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Como funciona?&lt;/strong&gt; Configura o produtor Kafka e oferece métodos para enviar mensagens, tanto individualmente como em lotes.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Consumidor de Eventos (&lt;code&gt;MessageConsumer&lt;/code&gt;):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;O que faz?&lt;/strong&gt; Recebe mensagens do Kafka e processa-as.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Como funciona?&lt;/strong&gt; Configura o consumidor Kafka, assina um tópico e, em um loop contínuo, consome mensagens. Se o processamento for bem-sucedido, confirma a mensagem. Em caso de falha, encaminha a mensagem para um tópico de dead letter.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Voce ainda pode criar uma classe program e testar a aplicação em um projeto console app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Threading&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Threading.Tasks&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Confluent.Kafka&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;KafkaConsoleApp&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;cts&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;CancellationTokenSource&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;producerTask&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;ProduceMessagesAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Token&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;consumerTask&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;ConsumeMessagesAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Token&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Pressione ENTER para encerrar..."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ReadLine&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

            &lt;span class="n"&gt;cts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Cancel&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

            &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WhenAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;producerTask&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;consumerTask&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;ProduceMessagesAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CancellationToken&lt;/span&gt; &lt;span class="n"&gt;cancellationToken&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ProducerConfig&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;BootstrapServers&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"localhost:9092"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
            &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;producer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ProducerBuilder&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;Build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;topic&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"meu-topico"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;cancellationToken&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsCancellationRequested&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;$"Mensagem de produção &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;++}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;producer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ProduceAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Value&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
                &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Produzida mensagem: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;ConsumeMessagesAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CancellationToken&lt;/span&gt; &lt;span class="n"&gt;cancellationToken&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ConsumerConfig&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;BootstrapServers&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"localhost:9092"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;GroupId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"test-group"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;AutoOffsetReset&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;AutoOffsetReset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Earliest&lt;/span&gt;
            &lt;span class="p"&gt;};&lt;/span&gt;

            &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;consumer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ConsumerBuilder&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Ignore&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;Build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="n"&gt;consumer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"meu-topico"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;cancellationToken&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsCancellationRequested&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;try&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;consumeResult&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;consumer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Consume&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cancellationToken&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Consumida mensagem: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;consumeResult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;OperationCanceledException&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="c1"&gt;// Ignore cancellation&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Erro ao consumir mensagem: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Kafka UI&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Geralmente o Kafka é somente uma aplicação em background rodando que você não consegue interagir diretamente, mas se você voltar no nosso docker-compose ali em cima vai perceber que a gente chamou o container do kafka-UI. Se você acessar o &lt;a href="http://localhost:8080"&gt;http://localhost:8080&lt;/a&gt; no seu navegador você irá poder desfrutar dessa interface do kafka onde você pode verificar as mensagens que chegam, os consumidores, os grupos, e tudo mais, permitindo assim gerenciar visualmente seu kafka.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Conclusão&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Nessa jornada pelo universo do Apache Kafka para .NET, mergulhamos fundo nos conceitos, desde o básico até colocar a mão na massa. O Kafka, esse maestro da comunicação assíncrona, nos mostrou como organizar o caos de eventos em tempo real de forma eficiente.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Considerações&lt;/strong&gt; Vimos até então o básico do Kafka: entendemos sua logica de funcionamento e implementamos um produtor consumidor básico, mas não para por aqui. Provavelmente eu trarei uma segunda parte desse artigo focando mais no lado técnico com estratégias de otimizações que podem ser aplicadas dentro de um ambiente onde o kafka é usado, reduzindo riscos e aumentando consistência do produto.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Então, galera, esse é só o começo! Bora explorar mais e desbravar as possibilidades do Kafka. O palco tá pronto, e a plateia (ou os tópicos, no caso) estão esperando por mais! 🚀🎉&lt;/p&gt;

</description>
      <category>kafka</category>
      <category>dotnet</category>
      <category>braziliandevs</category>
      <category>devops</category>
    </item>
    <item>
      <title>Descomplicando o Mundo da Programação - Um Guia sobre Dependency Injection, ciclo de vida Singleton, Scoped e Transient em .NET.</title>
      <dc:creator>Bruno Pizol Camargo</dc:creator>
      <pubDate>Fri, 23 Feb 2024 20:07:35 +0000</pubDate>
      <link>https://dev.to/brunopizol/descomplicando-o-mundo-da-programacao-um-guia-sobre-dependency-injection-singleton-scoped-e-transient-4efm</link>
      <guid>https://dev.to/brunopizol/descomplicando-o-mundo-da-programacao-um-guia-sobre-dependency-injection-singleton-scoped-e-transient-4efm</guid>
      <description>&lt;p&gt;Você durante sua caminhada pelo vasto universo da programação, provavelmente já esbarrou em termos como "Dependency Injection", "Singleton", "Scoped" e "Transient". Calma, não precisa entrar em pânico! Neste artigo, vamos desbravar esses conceitos sem firulas e numa linguagem que até a máquina de café vai entender. Prepare-se para uma jornada no mundo do desenvolvimento de software, onde vamos desvendar os segredos por trás dessas palavras que parecem complicadas, mas são mais amigas do que você imagina. Vamos nessa! 🚀&lt;/p&gt;

&lt;h2&gt;
  
  
  O que é dependency Injection?
&lt;/h2&gt;

&lt;p&gt;Dependency Injection é um padrão de design no desenvolvimento de software, no qual as dependências de uma classe são fornecidas de fora, em vez de serem criadas dentro da própria classe. Esse método promove a flexibilidade, manutenibilidade e testabilidade do código.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Imagina que você está construindo um jogo de videogame:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No jogo, você tem diferentes personagens, monstros e armas, certo? Agora, imagine que cada um desses personagens e objetos precisa de coisas para funcionar, como energia, habilidades especiais e até mesmo uma espada mágica.&lt;/p&gt;

&lt;p&gt;Em vez de construir todas essas coisas dentro de cada personagem ou objeto, o que pode ficar bagunçado, a Dependency Injection é como chamar alguém (um "injetor") para entregar essas coisas quando cada personagem ou objeto precisa delas.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resumindo:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Dependency Injection é como ter um assistente (ou "injetor") que organiza e fornece tudo o que seus personagens e objetos precisam para funcionar no jogo, para que você possa se concentrar em jogar sem se preocupar muito com os detalhes complicados de como cada coisa é feita. É uma maneira de tornar as coisas mais fáceis e organizadas no mundo da criação de jogos (ou qualquer outro tipo de software)!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F17ez6erfv0iigf4ge5na.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F17ez6erfv0iigf4ge5na.jpg" alt="Image description" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exemplo Prático de Dependency Injection:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Imagine que você está desenvolvendo uma aplicação web e precisa de um serviço de log para registrar eventos importantes. Utilizando Dependency Injection, você pode criar uma interface &lt;code&gt;ILogService&lt;/code&gt; e implementações específicas para diferentes ciclos de vida:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;ILogService&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SingletonLogService&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ILogService&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Implementação do log para Singleton&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ScopedLogService&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ILogService&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Implementação do log para Scoped&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TransientLogService&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ILogService&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Implementação do log para Transient&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No momento do registro do serviço na injeção de dependência, você pode escolher o ciclo de vida desejado:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Registro do serviço Singleton&lt;/span&gt;
&lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddSingleton&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ILogService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SingletonLogService&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Registro do serviço Scoped&lt;/span&gt;
&lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddScoped&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ILogService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ScopedLogService&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Registro do serviço Transient&lt;/span&gt;
&lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddTransient&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ILogService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TransientLogService&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Assim, ao longo do desenvolvimento, você pode escolher o ciclo de vida mais apropriado para o serviço de log, dependendo dos requisitos de sua aplicação.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vantagens da Dependency Injection:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Desacoplamento:&lt;/strong&gt; O uso de DI reduz o acoplamento entre os componentes da aplicação, tornando o código mais modular e fácil de entender.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Facilidade de Testes:&lt;/strong&gt; Injetar dependências torna mais fácil substituir implementações reais por versões de teste (mocks) durante os testes unitários.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexibilidade:&lt;/strong&gt; Permite alterar o comportamento de componentes da aplicação sem modificar o código fonte, facilitando a manutenção e a evolução do sistema.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reutilização de Componentes:&lt;/strong&gt; Componentes podem ser reutilizados em diferentes contextos, uma vez que as dependências podem ser facilmente trocadas.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Ciclo de vida Singleton
&lt;/h2&gt;

&lt;p&gt;Singleton é um padrão de design de software que garante a existência de apenas uma instância de uma classe em todo o programa e fornece um ponto global de acesso a essa instância. Em outras palavras, ele assegura que, independentemente de quantas vezes seja necessário, haverá apenas uma única ocorrência da classe durante a execução do programa.&lt;/p&gt;

&lt;p&gt;Imagine que você tem uma caixa especial onde guarda todas as suas coisas mais importantes, tipo um cofre só seu. Agora, o Singleton é um pouco como ter um superpoder que faz com que só exista uma caixa dessas no mundo todo. Ou seja, não importa quantas vezes você pedir, sempre vai ser a mesma caixa.&lt;/p&gt;

&lt;h3&gt;
  
  
  Resumindo
&lt;/h3&gt;

&lt;p&gt;Em termos de programação, o Singleton é um jeito de garantir que, não importa quantas vezes você precise usar algo (como uma caixa especial para guardar informações), só vai existir uma versão dessa "caixa" durante todo o programa. Isso é útil quando você quer ter certeza de que certas informações importantes são sempre as mesmas, não importa onde você esteja no código. É tipo ter um superpoder de organização para manter tudo no lugar certo!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhkzpp2jphyvqj1b916n9.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhkzpp2jphyvqj1b916n9.jpg" alt="Image description" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Padrão singleton vs ciclo de vida Singleton
&lt;/h2&gt;

&lt;p&gt;O termo "singleton" pode ser usado de duas maneiras relacionadas, mas diferentes, dependendo do contexto: o padrão de design Singleton e o ciclo de vida Singleton usado em injeção de dependência.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Padrão de Design Singleton:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Definição:&lt;/strong&gt; O padrão de design Singleton é um padrão de criação que garante que uma classe tenha apenas uma instância e fornece um ponto global de acesso a essa instância.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Características Principais:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Um construtor privado para evitar instancias externas.&lt;/li&gt;
&lt;li&gt;Uma propriedade ou método estático que retorna a única instância da classe.&lt;/li&gt;
&lt;li&gt;A instância é criada apenas quando necessário e, uma vez criada, é reutilizada.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Ciclo de Vida Singleton (Injeção de Dependência):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Definição:&lt;/strong&gt; No contexto da injeção de dependência (DI), o ciclo de vida Singleton refere-se à duração da existência de uma instância de um serviço específico gerenciado pelo contêiner de DI.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Características Principais:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Uma única instância do serviço é criada e compartilhada por todas as dependências que solicitam esse serviço.&lt;/li&gt;
&lt;li&gt;A instância persiste durante a vida do contêiner de injeção de dependência.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Diferenças:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;O padrão de design Singleton é uma abordagem mais ampla que se aplica a qualquer classe, independentemente de ser ou não gerenciada por um contêiner de injeção de dependência.&lt;/li&gt;
&lt;li&gt;O ciclo de vida Singleton em injeção de dependência é específico para o contexto de um contêiner de DI e se refere à maneira como as instâncias de serviços são gerenciadas e compartilhadas entre dependências.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Nesse texto estamos abordando somente o ciclo de vida Singleton, porém você pode encontrar sobre o padrão singleton nesse &lt;a href="https://dev.to/higordiego/padrao-singleton-4chj#:~:text=O%20padr%C3%A3o%20Singleton%20%C3%A9%20um%20padr%C3%A3o%20de%20projeto%20muito%20%C3%BAtil,acesso%20global%20para%20essa%20inst%C3%A2ncia."&gt;artigo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Benefícios:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Eficiência:&lt;/strong&gt; Reduz a sobrecarga de criação de instâncias, pois a mesma instância é compartilhada.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Manutenção de Estado:&lt;/strong&gt; Útil para serviços que precisam manter um estado global, como configuração ou armazenamento em cache.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cache de Dados:&lt;/strong&gt; Útil para serviços que precisam armazenar em cache dados que podem ser compartilhados por toda a aplicação.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Malefícios:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Memória:&lt;/strong&gt; Pode levar a um aumento no uso de memória, pois a instância persiste durante toda a vida da aplicação.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Concorrência:&lt;/strong&gt; Deve ser cuidadosamente projetado para ser thread-safe, já que a mesma instância é compartilhada entre threads.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Exemplo:&lt;/strong&gt;&lt;br&gt;
Imagine um serviço de configuração global que é usado por diferentes partes da aplicação:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppConfigurationService&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;AppName&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;// Outras propriedades e métodos de configuração&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Registro do serviço como Singleton&lt;/span&gt;
&lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddSingleton&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;AppConfigurationService&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Exemplo:&lt;/strong&gt;&lt;br&gt;
Vamos considerar um serviço de cache simples usando o ciclo de vida Singleton:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CacheService&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;Dictionary&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;object&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_cache&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Dictionary&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;object&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;AddToCache&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_cache&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="nf"&gt;GetFromCache&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;_cache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;TryGetValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Registro do serviço como Singleton&lt;/span&gt;
&lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddSingleton&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;CacheService&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Ciclo de vida Scoped
&lt;/h2&gt;

&lt;p&gt;Scoped é um padrão de design no desenvolvimento de software que cria uma instância de um objeto por solicitação ou contexto específico. Em outras palavras, uma nova instância do objeto é criada para cada "escopo" ou contexto determinado, garantindo que diferentes partes do programa possam ter suas próprias instâncias independentes. Isso é frequentemente utilizado em ambientes web, onde uma nova instância é criada para cada solicitação HTTP.&lt;/p&gt;

&lt;p&gt;Ok, imagine que você está jogando um game online e cada jogador tem sua própria área de jogo, certo? O "scoped" seria como criar uma mochila especial para cada jogador, e dentro dessa mochila, eles podem colocar suas próprias coisas.&lt;/p&gt;

&lt;p&gt;Agora, pense que cada vez que um jogador entra no jogo, uma nova mochila é feita só para ele. Essa mochila é usada só enquanto ele está jogando. Outro jogador entra? Pronto, uma nova mochila é feita só para ele também.&lt;/p&gt;

&lt;h3&gt;
  
  
  Resumindo
&lt;/h3&gt;

&lt;p&gt;Em programação, "scoped" funciona assim. Cada vez que algo precisa de uma mochila especial para fazer suas coisas, uma nova é criada só para aquela situação específica. Cada parte do jogo (ou do programa) tem sua própria mochila, sem confundir com a mochila de ninguém mais. É uma maneira organizada de manter as coisas separadas e arrumadinhas! 🎮&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvildx4yngu8hmrzlx7sw.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvildx4yngu8hmrzlx7sw.jpg" alt="Image description" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Benefícios:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Isolamento de Solicitação:&lt;/strong&gt; Garante que a instância é compartilhada apenas durante uma solicitação HTTP.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Manutenção de Estado por Solicitação:&lt;/strong&gt; Ideal para serviços que precisam manter um estado durante o processamento de uma única solicitação.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Contexto de Solicitação:&lt;/strong&gt; Ideal para serviços que precisam compartilhar informações específicas de uma solicitação, como dados do usuário.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Malefícios:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Memória:&lt;/strong&gt; Usa memória enquanto a solicitação está ativa, mas as instâncias são descartadas no final da solicitação.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Exemplo:&lt;/strong&gt;&lt;br&gt;
Suponha que você tenha um serviço de carrinho de compras em uma aplicação de comércio eletrônico:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ShoppingCartService&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_items&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;AddItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Item&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Outros métodos relacionados ao carrinho de compras&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Registro do serviço como Scoped&lt;/span&gt;
&lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddScoped&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ShoppingCartService&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Exemplo:&lt;/strong&gt;&lt;br&gt;
Suponha que você tenha um serviço de autenticação que precisa manter informações do usuário durante uma solicitação:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AuthenticationService&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt; &lt;span class="n"&gt;_currentUser&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;SetCurrentUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_currentUser&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt; &lt;span class="nf"&gt;GetCurrentuser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;_currentUser&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Registro do serviço como Scoped&lt;/span&gt;
&lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddScoped&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;AuthenticationService&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Ciclo de vida Transient
&lt;/h2&gt;

&lt;p&gt;Transient é um padrão de design em programação que cria uma nova instância de um objeto cada vez que é solicitado. Em termos mais simples, para cada vez que você precisa desse objeto, uma cópia fresquinha é feita na hora. Essa abordagem é útil quando se quer ter certeza de que cada solicitação recebe uma instância totalmente nova e independente.&lt;/p&gt;

&lt;p&gt;Ok, imagine que você está em uma máquina de sorvetes super high-tech. O "transient" seria como pedir um sorvete de baunilha sempre que você quiser. Cada vez que você pede, o sorveteiro faz um sorvete novinho só para você naquele momento.&lt;/p&gt;

&lt;p&gt;Traduzindo para a programação, "transient" funciona mais ou menos assim. Cada vez que alguma parte do programa pede por alguma coisa, como uma função ou um serviço, o sistema cria uma versão nova e fresquinha na hora, sem reaproveitar nada do que já existia. É como sempre ter o seu próprio sorvete de baunilha, garantindo que é sempre novinho em folha! 🍦&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Benefícios:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Leveza e Simplicidade:&lt;/strong&gt; Adequado para serviços que não precisam manter um estado significativo e são leves.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Malefícios:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Overhead de Criação:&lt;/strong&gt; Pode ter um leve impacto no desempenho, pois uma nova instância é criada para cada solicitação.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Exemplo:&lt;/strong&gt;&lt;br&gt;
Considere um serviço de geração de números aleatórios:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RandomNumberService&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;Random&lt;/span&gt; &lt;span class="n"&gt;_random&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Random&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;GetRandomNumber&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;_random&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Registro do serviço como Transient&lt;/span&gt;
&lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddTransient&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;RandomNumberService&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Exemplo:&lt;/strong&gt;&lt;br&gt;
Considere um serviço de geração de identificadores únicos usando o ciclo de vida Transient:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UniqueIdService&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;GenerateUniqueId&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Guid&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;NewGuid&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Registro do serviço como Transient&lt;/span&gt;
&lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddTransient&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;UniqueIdService&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Mas pera, Scoped e transient então não são a mesma coisa?
&lt;/h2&gt;

&lt;p&gt;Apesar de muito parecidos, não, não são a mesma coisa. Por exemplo vamos supor que eu tenho uma aplicação a onde eu faço uma requisição pro backend enviando o numero da minha conta bancaria:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;o backend vai buscar o valor do meu saldo no banco&lt;/li&gt;
&lt;li&gt;vai processar a operação que foi solicitada(deposito ou saque)&lt;/li&gt;
&lt;li&gt;vai salvar no banco o novo valor do meu saldo&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;nesse fluxo o &lt;em&gt;scoped&lt;/em&gt; &lt;strong&gt;abriria somente uma instancia para a operação de leitura, processamento e escrita depois descartaria a instancia&lt;/strong&gt;. enquanto que &lt;strong&gt;o &lt;em&gt;transient&lt;/em&gt; abriria uma nova instancia a cada operação totalizando 3 instancias&lt;/strong&gt; e ao final de cada operação iria descartando as instancias.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Considerações Práticas&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Agora que você já entende os conceitos e aplicações dessas 3 técnicas vamos a considerações praticas sobre cada:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Singleton - Considerações Práticas:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Compartilhamento de Estado:&lt;/strong&gt; Útil quando há a necessidade de compartilhar um estado global entre diferentes partes da aplicação.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Configuração e Logging:&lt;/strong&gt; Pode ser aplicado a serviços de configuração, logging e caching, onde manter uma única instância é benéfico.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cuidado com Objetos Grandes:&lt;/strong&gt; Evite armazenar objetos grandes ou pesados em serviços Singleton, pois isso pode resultar em um consumo significativo de memória.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Scoped - Considerações Práticas:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Estado por Solicitação:&lt;/strong&gt; Ideal para serviços que precisam manter um estado específico durante o processamento de uma única solicitação HTTP.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Evitar Escopo Manual:&lt;/strong&gt; Evite criar escopos manualmente, pois a injeção de dependência e o ciclo de vida Scoped são gerenciados automaticamente pelo framework.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Transient - Considerações Práticas:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Serviços Leves e Sem Estado:&lt;/strong&gt; Melhor para serviços leves, sem estado significativo, onde uma nova instância é desejada para cada solicitação.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Evitar Armazenamento de Estado:&lt;/strong&gt; Evite armazenar um estado significativo em serviços Transient, pois isso pode levar a uma alta sobrecarga de criação de instâncias.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Melhores Práticas Gerais:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Entendimento do Contexto:&lt;/strong&gt; Escolha o ciclo de vida com base na necessidade e no contexto específico de cada serviço.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Evitar Vazamentos de Memória:&lt;/strong&gt; Ao usar Singleton, evite referências que podem impedir a coleta de lixo, levando a vazamentos de memória.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Thread Safety:&lt;/strong&gt; Ao usar Singleton, garanta que a implementação seja thread-safe, pois a mesma instância é compartilhada entre várias threads.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Logica de Negócios em Serviços Transient:&lt;/strong&gt; Evite colocar lógica de negócios significativa em serviços Transient, pois isso pode levar a um alto custo de criação de instâncias.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Revisão Periódica:&lt;/strong&gt; Reavalie periodicamente a escolha do ciclo de vida à medida que os requisitos da aplicação evoluem.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Casos de Uso Específicos:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Singleton para Configuração:&lt;/strong&gt; Use Singleton para serviços de configuração que precisam ser carregados uma vez e compartilhados em toda a aplicação.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scoped para Autenticação:&lt;/strong&gt; Utilize Scoped para serviços de autenticação que precisam manter informações do usuário durante uma solicitação.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transient para Geração Aleatória:&lt;/strong&gt; Aplique Transient para serviços que realizam operações leves e sem estado, como geração de números aleatórios.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Considerações para Escalabilidade:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Singleton em Ambientes Distribuídos:&lt;/strong&gt; Ao escalar horizontalmente (adicionando mais instâncias) em ambientes distribuídos, o uso de Singleton pode resultar em compartilhamento de estado indesejado. Considere alternativas como armazenamento distribuído.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Impacto na Escala Vertical:&lt;/strong&gt; O uso excessivo de Singleton pode impactar a escalabilidade vertical (adicionando mais recursos a uma única instância). Avalie o impacto na memória e nos recursos do servidor.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Conclusão:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Entender os ciclos de vida dos serviços e aplicar adequadamente o Dependency Injection é crucial para o desenvolvimento de software eficiente e escalável. Cada ciclo de vida tem seus benefícios e desafios, e a escolha certa depende das características específicas de cada serviço e da arquitetura da aplicação. A adoção de boas práticas e considerações práticas contribuirá para um design mais robusto e fácil de manter.&lt;/p&gt;

</description>
      <category>braziliandevs</category>
      <category>dotnet</category>
      <category>csharp</category>
      <category>learning</category>
    </item>
    <item>
      <title>Evitando o Abuso do Else: Estratégias e Boas Práticas em Programação em C#</title>
      <dc:creator>Bruno Pizol Camargo</dc:creator>
      <pubDate>Sun, 18 Feb 2024 23:12:14 +0000</pubDate>
      <link>https://dev.to/brunopizol/evitando-o-abuso-do-else-estrategias-e-boas-praticas-em-programacao-com-exemplos-em-c-496n</link>
      <guid>https://dev.to/brunopizol/evitando-o-abuso-do-else-estrategias-e-boas-praticas-em-programacao-com-exemplos-em-c-496n</guid>
      <description>&lt;p&gt;Desenvolver software claro e legível é fundamental para a manutenção e compreensão eficaz do código. Recentemente, uma discussão significativa surgiu na comunidade tech do Twitter sobre a recusa de Pull Requests (PRs) quando o &lt;code&gt;else&lt;/code&gt; é usado. A justificativa é que o &lt;code&gt;else&lt;/code&gt; prejudica a legibilidade e que há várias técnicas para evitar seu uso. Sendo assim, quais seriam essas formas para evitar o uso indiscriminado do &lt;code&gt;else&lt;/code&gt;? Abaixo, apresento uma lista de estratégias para contornar o uso do &lt;code&gt;else&lt;/code&gt;, destacando os pontos fortes e fracos de cada alternativa.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Early Return:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Pontos Fortes:&lt;/em&gt;

&lt;ul&gt;
&lt;li&gt;Reduz a profundidade dos blocos, facilitando a leitura.&lt;/li&gt;
&lt;li&gt;Evita a necessidade de aninhar várias condições &lt;code&gt;else&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Pontos Fracos:&lt;/em&gt;

&lt;ul&gt;
&lt;li&gt;Pode resultar em múltiplos pontos de retorno no código.&lt;/li&gt;
&lt;li&gt;Alguns desenvolvedores consideram isso uma má prática, pois atrapalha o fluxo de debug da aplicação.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;ValidarDados&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;dados&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dados&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="n"&gt;dados&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Count&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Restante da lógica de validação&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Mapping com Dictionary em C#:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Pontos Fortes:&lt;/em&gt;

&lt;ul&gt;
&lt;li&gt;Simplifica a lógica, associando valores a comportamentos.&lt;/li&gt;
&lt;li&gt;Reduz a necessidade de blocos &lt;code&gt;else&lt;/code&gt; ao utilizar mapeamentos.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Pontos Fracos:&lt;/em&gt;

&lt;ul&gt;
&lt;li&gt;Pode aumentar a complexidade se o mapeamento for extenso.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;Dictionary&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Func&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;operacoes&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Dictionary&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Func&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s"&gt;"soma"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s"&gt;"subtracao"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;resultado&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;operacoes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"soma"&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Break the Chain em .NET:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Pontos Fortes:&lt;/em&gt;

&lt;ul&gt;
&lt;li&gt;Divide operações complexas em etapas, facilitando a compreensão.&lt;/li&gt;
&lt;li&gt;Reduz a necessidade de blocos &lt;code&gt;else&lt;/code&gt; ao retornar antecipadamente.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Pontos Fracos:&lt;/em&gt;

&lt;ul&gt;
&lt;li&gt;Pode levar a muitas funções pequenas, tornando o código fragmentado.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Resultado&lt;/span&gt; &lt;span class="nf"&gt;ProcessarDados&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;dados&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="nf"&gt;ValidarDados&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dados&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Processamento adicional&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;resultadoFinal&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Move Nested Blocks em C#:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Pontos Fortes:&lt;/em&gt;

&lt;ul&gt;
&lt;li&gt;Melhora a legibilidade ao mover condições aninhadas para funções separadas.&lt;/li&gt;
&lt;li&gt;Facilita testes unitários de cada condição isoladamente.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Pontos Fracos:&lt;/em&gt;

&lt;ul&gt;
&lt;li&gt;Introduz mais funções no escopo.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;VerificarCondicao1&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Lógica da condição 1&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;VerificarCondicao2&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Lógica da condição 2&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;VerificarCondicao1&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Lógica quando a condição 1 é verdadeira&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;VerificarCondicao2&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Lógica quando a condição 2 é verdadeira&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Uso de Strategy Pattern em C#:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Pontos Fortes:&lt;/em&gt;

&lt;ul&gt;
&lt;li&gt;Encapsula algoritmos em classes, eliminando a necessidade de &lt;code&gt;else&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Facilita a extensão do código com novas estratégias.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Pontos Fracos:&lt;/em&gt;

&lt;ul&gt;
&lt;li&gt;Pode ser excessivo para problemas simples, na maioria dos casos é como usar uma bazuca para matar uma mosca
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;IEstrategia&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Executar&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EstrategiaA&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IEstrategia&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Executar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Lógica da Estratégia A&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EstrategiaB&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IEstrategia&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Executar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Lógica da Estratégia B&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;IEstrategia&lt;/span&gt; &lt;span class="n"&gt;estrategia&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;EstrategiaA&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Estratégia inicial&lt;/span&gt;
&lt;span class="n"&gt;estrategia&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Executar&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Executa a Estratégia A&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Uso de Ternário para Melhorar Legibilidade em C#:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Pontos Fortes:&lt;/em&gt;

&lt;ul&gt;
&lt;li&gt;Em expressões curtas, proporciona uma alternativa legível.&lt;/li&gt;
&lt;li&gt;Reduz a necessidade de blocos &lt;code&gt;else&lt;/code&gt; em situações simples.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Pontos Fracos:&lt;/em&gt;

&lt;ul&gt;
&lt;li&gt;Pode se tornar confuso em expressões longas.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pontuacao&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="m"&gt;70&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="s"&gt;"Aprovado"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Reprovado"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Conclusão:
&lt;/h3&gt;

&lt;p&gt;Evitar o abuso do &lt;code&gt;else&lt;/code&gt; é crucial para manter o código claro e legível em C#. Cada estratégia tem seus pontos fortes e fracos, e a escolha depende da complexidade do problema. Utilizando essas abordagens com sabedoria, os desenvolvedores podem criar um código mais robusto, legível e fácil de manter em projetos .NET.&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>learning</category>
      <category>codenewbie</category>
      <category>braziliandevs</category>
    </item>
  </channel>
</rss>
