<?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: Gabriel Batista</title>
    <description>The latest articles on DEV Community by Gabriel Batista (@devgabrielb).</description>
    <link>https://dev.to/devgabrielb</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%2F584610%2F048f63c0-1644-4949-9384-358c4f0d9558.png</url>
      <title>DEV Community: Gabriel Batista</title>
      <link>https://dev.to/devgabrielb</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/devgabrielb"/>
    <language>en</language>
    <item>
      <title>Aplicando DDD: Antes do tático, vem o domínio</title>
      <dc:creator>Gabriel Batista</dc:creator>
      <pubDate>Tue, 02 Jun 2026 16:25:47 +0000</pubDate>
      <link>https://dev.to/devgabrielb/aplicando-ddd-antes-do-tatico-vem-o-dominio-2h5</link>
      <guid>https://dev.to/devgabrielb/aplicando-ddd-antes-do-tatico-vem-o-dominio-2h5</guid>
      <description>&lt;h2&gt;
  
  
  Introdução
&lt;/h2&gt;

&lt;p&gt;Quando comecei a estudar DDD, minha atenção foi quase toda para a parte tática. Queria entender como organizar o código, criar uma boa estrutura de pastas e aplicar aqueles padrões que apareciam em artigos, vídeos e repositórios no GitHub: &lt;em&gt;aggregate&lt;/em&gt;, &lt;em&gt;value object&lt;/em&gt;, &lt;em&gt;domain event&lt;/em&gt;, &lt;em&gt;repository&lt;/em&gt;, &lt;em&gt;domain service&lt;/em&gt;, &lt;em&gt;CQRS&lt;/em&gt;, &lt;em&gt;event sourcing&lt;/em&gt; e por aí vai.&lt;/p&gt;

&lt;p&gt;Na minha cabeça, aplicar DDD era muito sobre conseguir montar uma arquitetura bonita, com as responsabilidades bem separadas e nomes que pareciam fazer sentido. Enquanto isso, alguns conceitos como &lt;strong&gt;linguagem ubíqua&lt;/strong&gt;, &lt;strong&gt;bounded context&lt;/strong&gt;, &lt;strong&gt;context map&lt;/strong&gt;... acabavam ficando em segundo plano. Eu até sabia que eles existiam, mas pareciam uma etapa mais abstrata, teórica demais, antes da parte que realmente me interessava: escrever código.&lt;/p&gt;

&lt;p&gt;Depois de alguns projetos de exemplo, comecei a perceber um padrão. No começo tudo parecia organizado, mas conforme o domínio crescia, as decisões começavam a ficar confusas. Precisava combinar vários agregados, criava serviços de domínio para resolver regras que ainda não entendia bem, movia responsabilidades de um lado para o outro e tentava encaixar mais um padrão que parecesse resolver a situação.&lt;/p&gt;

&lt;p&gt;O problema é que eu ainda não sabia exatamente o que queria construir. Seguia uma lista de padrões sem entender, de fato, o motivo por trás de cada um. O resultado era um software tecnicamente organizado, mas pouco conectado com a realidade do negócio.&lt;/p&gt;

&lt;p&gt;Este artigo abre uma série de textos inspirada nas discussões do clube do livro da &lt;a href="https://www.linkedin.com/company/tech-leads-club/" rel="noopener noreferrer"&gt;Tech Leads Club&lt;/a&gt;. O livro que estamos lendo é &lt;a href="https://a.co/d/07ctxOfw" rel="noopener noreferrer"&gt;&lt;em&gt;Learning Domain-Driven Design: Aligning Software Architecture and Business Strategy&lt;/em&gt;&lt;/a&gt;, e a proposta aqui é usar essa leitura como ponto de partida para organizar meu entendimento e aplicar essas ideias na construção de um sistema.&lt;/p&gt;

&lt;p&gt;Neste primeiro texto, vamos começar justamente por onde eu deveria ter começado: o DDD estratégico. Antes de falar sobre código, vamos olhar para domínio e os subdomínios usando como exemplo o domínio de &lt;strong&gt;Turismo&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  DDD estratégico
&lt;/h3&gt;

&lt;p&gt;A ideia do DDD estratégico não é começar desenhando pastas, classes ou camadas da aplicação. Antes disso, precisamos entender em que domínio estamos trabalhando, quais partes desse domínio são mais importantes para o negócio, quais problemas precisam ser resolvidos e quais conceitos fazem sentido para as pessoas que vivem aquele contexto no dia a dia.&lt;/p&gt;

&lt;p&gt;Essa etapa ajuda a responder perguntas como:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Qual é o problema principal que o software precisa resolver?&lt;/li&gt;
&lt;li&gt;Onde está o diferencial do negócio?&lt;/li&gt;
&lt;li&gt;Quais partes do sistema merecem mais investimento de modelagem?&lt;/li&gt;
&lt;li&gt;Onde um mesmo termo pode ter significados diferentes dependendo do contexto?&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Conceitos fundamentais
&lt;/h4&gt;

&lt;p&gt;O primeiro é &lt;strong&gt;domínio&lt;/strong&gt;. No DDD, domínio é a área de atividade que o software precisa compreender. É o pedaço da realidade em que a empresa atua e onde o sistema precisa fazer sentido. &lt;/p&gt;

&lt;p&gt;O segundo é &lt;strong&gt;subdomínio&lt;/strong&gt;. Um subdomínio é uma parte menor e mais específica dentro desse domínio maior. Ele representa um recorte do problema de negócio.&lt;/p&gt;

&lt;p&gt;O terceiro é o &lt;strong&gt;especialista de domínio&lt;/strong&gt;. O especialista de domínio é a pessoa que conhece o problema de verdade. É quem entende as regras, as exceções, os conflitos, os termos usados na operação e o que realmente importa para o negócio. Nem sempre essa pessoa é alguém de tecnologia. Muitas vezes ela está em áreas como atendimento, operações, vendas, financeiro, produto ou gestão.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Disclaimer&lt;/em&gt;: como este artigo é um exercício, eu mesmo vou assumir o papel de &lt;strong&gt;especialista de domínio&lt;/strong&gt; :)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  O que é domínio?
&lt;/h3&gt;

&lt;p&gt;Quando falamos de domínio no DDD, estamos falando da área da realidade que precisa ser entendida para que o sistema cumpra seu papel. Se estamos falando de um e-commerce, o domínio está ligado à operação de venda. Se estamos falando de uma plataforma de streaming, o domínio está ligado à distribuição e ao consumo de mídia.&lt;/p&gt;

&lt;p&gt;No nosso caso, dizer apenas que o domínio é &lt;strong&gt;Turismo&lt;/strong&gt; ainda é abstrato demais. É parecido com dizer que o domínio da Uber é transporte urbano. Não está errado, mas ainda não ajuda muito a entender o problema de verdade.&lt;/p&gt;

&lt;p&gt;Então precisamos refinar. O nosso recorte aqui será &lt;strong&gt;Turismo de Experiência&lt;/strong&gt;. A ideia é oferecer uma experiência completa, facilitando a escolha de hospedagens, guias, roteiros e experiências locais. Nosso software fica responsável por fazer o melhor match entre turistas, guias e rotas com base no perfil e nos gostos do cliente, tornando o processo da viagem algo mais simples.&lt;/p&gt;

&lt;p&gt;Percebe que aqui já começa a aparecer uma pista importante? O sistema não quer só listar opções. Ele quer montar uma experiência personalizada na hora de escolher sua viagem. E isso ajuda a entender onde talvez esteja o diferencial do negócio.&lt;/p&gt;

&lt;h3&gt;
  
  
  Onde entram os subdomínios?
&lt;/h3&gt;

&lt;p&gt;Sabemos qual é o domínio e já temos uma noção melhor do que queremos fazer. A próxima pergunta é: o que realmente diferencia nossa empresa? O que fazemos com maestria que pode virar vantagem competitiva?&lt;/p&gt;

&lt;p&gt;Para responder isso, precisamos quebrar um pouco mais o problema. É aí que entram os subdomínios.&lt;/p&gt;

&lt;p&gt;Um jeito simples de pensar é assim:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;domínio é o problema maior que a empresa quer resolver&lt;/li&gt;
&lt;li&gt;subdomínio é uma parte coerente desse problema&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No nosso exemplo, o problema que a parte de gestão dos roteiros resolve é diferente do problema de gerenciar parceiros. O problema de reservas é diferente do problema de pagamentos. Tudo está dentro do mesmo domínio, mas não representa a mesma coisa.&lt;/p&gt;

&lt;p&gt;Uma heurística boa aqui é olhar para conjuntos coerentes de casos de uso: se os mesmos atores, os mesmos dados e as mesmas regras aparecem juntos com frequência, existe um bom sinal de que ali temos um subdomínio separado.&lt;/p&gt;

&lt;h2&gt;
  
  
  Subdomínios
&lt;/h2&gt;

&lt;p&gt;No nosso contexto, em que estamos desenvolvendo um software novo, a gente ainda vai descobrir onde estão esses subdomínios. Em uma empresa já estabelecida, isso costuma aparecer de forma mais natural na própria operação: atendimento, marketing, financeiro, operações e por aí vai.&lt;/p&gt;

&lt;p&gt;Depois de mapear os subdomínios, precisamos classificá-los entre &lt;strong&gt;Core&lt;/strong&gt;, &lt;strong&gt;Generic&lt;/strong&gt; e &lt;strong&gt;Supporting&lt;/strong&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tipo&lt;/th&gt;
&lt;th&gt;O que representa&lt;/th&gt;
&lt;th&gt;Estratégia&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Core&lt;/td&gt;
&lt;td&gt;Parte mais valiosa e mais ligada ao diferencial do negócio&lt;/td&gt;
&lt;td&gt;Mais investimento, mais cuidado e modelagem mais rica&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Generic&lt;/td&gt;
&lt;td&gt;Coisas que quase toda empresa precisa&lt;/td&gt;
&lt;td&gt;Comprar, integrar ou resolver da forma mais simples possível&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Supporting&lt;/td&gt;
&lt;td&gt;Partes importantes, mas que não são o diferencial principal&lt;/td&gt;
&lt;td&gt;Construir de forma objetiva, sem sofisticar demais&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Quando falamos de &lt;strong&gt;Core&lt;/strong&gt;, estamos nos referindo à parte principal do software, onde mora a vantagem competitiva. É onde faz sentido colocar mais energia, mais atenção e as melhores cabeças da equipe.&lt;/p&gt;

&lt;p&gt;O &lt;strong&gt;Generic&lt;/strong&gt; é aquilo que todo mundo faz. Algo que a gente até pode desenvolver, mas que muitas vezes faz mais sentido contratar ou integrar. Exemplos clássicos são gateways de pagamento, OAuth, autenticação e envio de e-mails.&lt;/p&gt;

&lt;p&gt;Por fim, temos o &lt;strong&gt;Supporting&lt;/strong&gt;, que apoia o negócio principal mas não é o centro dele. Normalmente aqui aparecem regras importantes, só que mais simples, sem exigir o mesmo nível de modelagem que o core.&lt;/p&gt;

&lt;p&gt;Também vale um detalhe: isso não é regra absoluta. Auth e pagamentos normalmente entram como genéricos, mas, em alguns contextos, uma empresa pode escolher manter isso internamente por custo, escala, compliance ou estratégia. DDD não manda comprar tudo. DDD manda pensar.&lt;/p&gt;

&lt;h3&gt;
  
  
  Uma matriz simples para pensar nisso
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspecto&lt;/th&gt;
&lt;th&gt;Core&lt;/th&gt;
&lt;th&gt;Generic&lt;/th&gt;
&lt;th&gt;Supporting&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Vantagem competitiva&lt;/td&gt;
&lt;td&gt;Sim&lt;/td&gt;
&lt;td&gt;Não&lt;/td&gt;
&lt;td&gt;Não&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Complexidade&lt;/td&gt;
&lt;td&gt;Alta&lt;/td&gt;
&lt;td&gt;Pode ser alta, mas comum ao mercado&lt;/td&gt;
&lt;td&gt;Baixa a média&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Volatilidade&lt;/td&gt;
&lt;td&gt;Alta&lt;/td&gt;
&lt;td&gt;Geralmente baixa&lt;/td&gt;
&lt;td&gt;Baixa a média&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Estratégia&lt;/td&gt;
&lt;td&gt;Investir forte&lt;/td&gt;
&lt;td&gt;Comprar, integrar ou reaproveitar&lt;/td&gt;
&lt;td&gt;Resolver sem sofisticar demais&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Time&lt;/td&gt;
&lt;td&gt;Mais experiente&lt;/td&gt;
&lt;td&gt;Pode ser vendor ou solução pronta&lt;/td&gt;
&lt;td&gt;Pode evoluir junto com o produto&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Os subdomínios do nosso exemplo
&lt;/h3&gt;

&lt;p&gt;Se olharmos para o problema descrito até aqui, uma primeira lista de subdomínios seria algo como:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Curadoria e match de experiências&lt;/li&gt;
&lt;li&gt;Gestão de ofertas&lt;/li&gt;
&lt;li&gt;Gestão de parceiros&lt;/li&gt;
&lt;li&gt;Reserva e disponibilidade&lt;/li&gt;
&lt;li&gt;Pagamentos&lt;/li&gt;
&lt;li&gt;Identidade e acesso&lt;/li&gt;
&lt;li&gt;Notificações&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Considerando que o diferencial da nossa empresa está em montar a melhor experiência possível para cada turista, então &lt;strong&gt;curadoria e match de experiências&lt;/strong&gt; provavelmente é o nosso &lt;strong&gt;Core Domain&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Uma classificação inicial poderia ficar assim:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Subdomínio&lt;/th&gt;
&lt;th&gt;Classificação&lt;/th&gt;
&lt;th&gt;Papel no negócio&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Curadoria e match de experiências&lt;/td&gt;
&lt;td&gt;Core&lt;/td&gt;
&lt;td&gt;Encontrar a melhor combinação entre perfil do turista, guia, roteiro e experiência&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gestão de ofertas&lt;/td&gt;
&lt;td&gt;Supporting&lt;/td&gt;
&lt;td&gt;Organizar roteiros, pacotes, hospedagens e eventos como opções ofertáveis ao turista&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gestão de parceiros&lt;/td&gt;
&lt;td&gt;Supporting&lt;/td&gt;
&lt;td&gt;Gerenciar guias, anfitriões e outros prestadores, com perfis, especialidades, idiomas e disponibilidade&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reserva e disponibilidade&lt;/td&gt;
&lt;td&gt;Supporting&lt;/td&gt;
&lt;td&gt;Coordenar consulta de disponibilidade, bloqueio de vagas, confirmação, cancelamento e regras de reserva&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pagamentos&lt;/td&gt;
&lt;td&gt;Generic&lt;/td&gt;
&lt;td&gt;Cobrança, repasse e confirmação financeira&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Identidade e acesso&lt;/td&gt;
&lt;td&gt;Generic&lt;/td&gt;
&lt;td&gt;Login, identidade e controle de acesso&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Notificações&lt;/td&gt;
&lt;td&gt;Generic&lt;/td&gt;
&lt;td&gt;E-mails, push e mensagens operacionais&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Essa classificação ainda pode mudar, porque ela depende da estratégia da empresa. Se amanhã o grande diferencial passar a ser a montagem inteligente de roteiros, &lt;strong&gt;Gestão de ofertas&lt;/strong&gt; pode subir de importância e até se fundir com o core. O objetivo aqui não é congelar o desenho, e sim começar a enxergar onde vale investir nosso esforço.&lt;/p&gt;

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

&lt;p&gt;No próximo artigo vamos continuar refinando nossos subdomínios e falar um pouco sobre linguagem ubíqua.&lt;/p&gt;

</description>
      <category>ddd</category>
      <category>programming</category>
      <category>braziliandevs</category>
      <category>learning</category>
    </item>
    <item>
      <title>Como Resolver o Erro DbUpdateConcurrencyException no Entity Framework</title>
      <dc:creator>Gabriel Batista</dc:creator>
      <pubDate>Fri, 03 Jan 2025 05:38:52 +0000</pubDate>
      <link>https://dev.to/devgabrielb/como-resolver-o-erro-dbupdateconcurrencyexception-no-entity-framework-392k</link>
      <guid>https://dev.to/devgabrielb/como-resolver-o-erro-dbupdateconcurrencyexception-no-entity-framework-392k</guid>
      <description>&lt;p&gt;&lt;strong&gt;Se você estiver gerando seus próprios IDs ao usar Entity Framework e se deparar com um erro de concorrência, essa dica pode te ajudar!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Recentemente, enfrentei um problema interessante ao trabalhar com Entity Framework: um &lt;strong&gt;DbUpdateConcurrencyException&lt;/strong&gt; aparentemente inexplicável ao tentar salvar novas entidades.&lt;/p&gt;

&lt;p&gt;A funcionalidade era simples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Recuperar um Grupo do banco&lt;/li&gt;
&lt;li&gt;Adicionar um Membro ao Grupo&lt;/li&gt;
&lt;li&gt;Salvar tudo&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;O código parecia correto, mas sempre recebia:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;DbUpdateConcurrencyException: The database operation was expected to affect 1 row&lt;span class="o"&gt;(&lt;/span&gt;s&lt;span class="o"&gt;)&lt;/span&gt;, but actually affected 0 row&lt;span class="o"&gt;(&lt;/span&gt;s&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;O que acontece?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Esse erro ocorre porque, por padrão, o Entity Framework assume a responsabilidade de gerar e gerenciar os valores das chaves primárias das entidades. Quando você define manualmente um valor para uma chave que normalmente seria gerada, a entidade será rastreada como "&lt;strong&gt;Modified&lt;/strong&gt;" em vez de "&lt;strong&gt;Added&lt;/strong&gt;" e quando uma entidade é marcada como "&lt;strong&gt;Modified&lt;/strong&gt;" em vez de "&lt;strong&gt;Added&lt;/strong&gt;", o EF tenta fazer um &lt;strong&gt;UPDATE&lt;/strong&gt; no banco em vez de um &lt;strong&gt;INSERT&lt;/strong&gt; mas não existe registro para atualizar (é uma nova entidade)&lt;/p&gt;

&lt;p&gt;Esse erro ocorre porque, por padrão, o Entity Framework assume a responsabilidade de gerar e gerenciar os valores das chaves primárias das entidades. Quando você define manualmente um valor para uma chave que normalmente seria gerada, a entidade é rastreada como "Modified" em vez de "&lt;strong&gt;Added&lt;/strong&gt;". Como resultado, o EF  tenta realizar um &lt;strong&gt;UPDATE&lt;/strong&gt; no banco de dados em vez de um &lt;strong&gt;INSERT&lt;/strong&gt;, mas não existe nenhum registro para atualizar (é uma nova entidade).&lt;/p&gt;

&lt;p&gt;A solução? Configure explicitamente que a chave primária não deve ser gerada automaticamente. Isso pode ser feito no &lt;strong&gt;Fluent API:&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="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Property&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;t&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="nf"&gt;ValueGeneratedNever&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Ou com &lt;strong&gt;data annotations&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="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;DatabaseGenerated&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DatabaseGeneratedOption&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;None&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;Id&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Espero que essa dica ajude você a evitar horas de debugging! 😉&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>ef</category>
      <category>entityframeworkcore</category>
      <category>csharp</category>
    </item>
    <item>
      <title>Seu Primeiro Pacote NuGet: Um Passo a Passo Prático</title>
      <dc:creator>Gabriel Batista</dc:creator>
      <pubDate>Fri, 03 Jan 2025 05:33:35 +0000</pubDate>
      <link>https://dev.to/devgabrielb/seu-primeiro-pacote-nuget-um-passo-a-passo-pratico-1o4n</link>
      <guid>https://dev.to/devgabrielb/seu-primeiro-pacote-nuget-um-passo-a-passo-pratico-1o4n</guid>
      <description>&lt;p&gt;Quando você trabalha em diferentes aplicações, é comum se deparar com os mesmos problemas e as mesmas soluções aparecendo de novo e de novo. Isso faz parte do dia a dia de um desenvolvedor, mas pode ser meio cansativo. Agora, imagine se você pudesse pegar esse código repetido, organizar direitinho e usar facilmente em outros projetos. Legal, né? Neste artigo, vamos explorar como fazer isso com o NuGet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Visão geral:
&lt;/h2&gt;

&lt;p&gt;O NuGet é o gerenciador de pacotes oficial do .NET e ajuda você a empacotar, compartilhar e usar funcionalidades reutilizáveis de forma simples. Com ele, dá para organizar seu código em pacotes, reaproveitá-los em outros projetos e até colaborar de maneira mais prática com outros desenvolvedores.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;"Um pacote NuGet é um arquivo ZIP com a extensão .nupkg que contém código compilado (DLLs), arquivos relacionados e um manifesto descritivo com informações como o número da versão. Desenvolvedores criam e publicam pacotes, enquanto consumidores obtêm e utilizam suas funcionalidades. O NuGet gerencia os detalhes intermediários."&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Criando um projeto
&lt;/h2&gt;

&lt;p&gt;Antes de começar, crie uma conta no &lt;a href="https://www.nuget.org/" rel="noopener noreferrer"&gt;NuGet.org&lt;/a&gt;. Isso será necessário para publicar seu pacote.&lt;/p&gt;

&lt;p&gt;Crie um projeto do tipo &lt;strong&gt;Class Library&lt;/strong&gt;. No terminal, execute:&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;dotnet&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;classlib&lt;/span&gt; &lt;span class="p"&gt;--&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="n"&gt;ExamplePackage&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Em seguida, abra o projeto em seu editor de preferência. Vamos criar um exemplo simples que converte um objeto em uma string JSON.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7y48cfl467arr7olqu5b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7y48cfl467arr7olqu5b.png" alt="Código do pacote" width="590" height="310"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Definindo os Metadados
&lt;/h2&gt;

&lt;p&gt;Para criar um pacote, é necessário configurar informações importantes diretamente no arquivo .&lt;strong&gt;csproj&lt;/strong&gt; do projeto. Esse arquivo define os metadados essenciais que identificarão seu pacote no NuGet.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Metadados Obrigatórios:&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;TargetFramework&lt;/strong&gt;: Define a versão do .NET que seu projeto utilizará.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PackageId&lt;/strong&gt;: Um identificador único para seu pacote.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Version&lt;/strong&gt;: Versão do pacote no formato Major.Minor.Patch (&lt;a href="https://semver.org/" rel="noopener noreferrer"&gt;SemVer&lt;/a&gt;).

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Major&lt;/strong&gt;: Alterações que quebram compatibilidade.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Minor&lt;/strong&gt;: Novas funcionalidades.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Patch&lt;/strong&gt;: Correções de bugs.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Metadados opcionais (não obrigatórios mas fortemente recomendados):&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Authors&lt;/strong&gt; Nome do autor ou autores do pacote.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Description&lt;/strong&gt;: Uma breve descrição do propósito do pacote.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PackageLicenseExpression&lt;/strong&gt;: Especifica a licença sob a qual o pacote é distribuído.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Atualize o arquivo .&lt;strong&gt;csproj&lt;/strong&gt; para incluir essas informações:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F89870cwcsdoy3k0jydm2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F89870cwcsdoy3k0jydm2.png" alt="Arquivo .csproj" width="777" height="367"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Compilando o pacote
&lt;/h2&gt;

&lt;p&gt;Com os metadados configurados, é hora de compilar o pacote. No terminal, execute:&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;dotnet&lt;/span&gt; &lt;span class="n"&gt;pack&lt;/span&gt; &lt;span class="p"&gt;--&lt;/span&gt;&lt;span class="n"&gt;configuration&lt;/span&gt; &lt;span class="n"&gt;Release&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esse comando criará um arquivo .&lt;strong&gt;nupkg&lt;/strong&gt; na pasta bin/Release.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0hqb023yysu4xs6z90ov.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0hqb023yysu4xs6z90ov.png" alt="Localização do pacote compilado" width="366" height="206"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Testando localmente
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Configurando a Fonte Local:&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Dentro do projeto, crie uma pasta para os pacotes locais:&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;mkdir&lt;/span&gt; &lt;span class="n"&gt;NuGetLocal&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copie o arquivo .&lt;strong&gt;nupkg&lt;/strong&gt; gerado para essa pasta:&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;cp&lt;/span&gt; &lt;span class="n"&gt;bin&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;Release&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;examplePackage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Convert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="m"&gt;1.0&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="n"&gt;nupkg&lt;/span&gt; &lt;span class="n"&gt;NuGetLocal&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adicione a pasta como uma fonte NuGet:&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;dotnet&lt;/span&gt; &lt;span class="n"&gt;nuget&lt;/span&gt; &lt;span class="k"&gt;add&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;caminho&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;completo&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;para&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;NuGetLocal&lt;/span&gt; &lt;span class="p"&gt;--&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="n"&gt;NuGetLocal&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Consumindo o Pacote no Projeto:&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Você pode criar um projeto console para testes:&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;dotnet&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;console&lt;/span&gt; &lt;span class="p"&gt;--&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="n"&gt;ExamplePackageTest&lt;/span&gt;
&lt;span class="n"&gt;cd&lt;/span&gt; &lt;span class="n"&gt;ExamplePackageTest&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use o comando dotnet add package para instalar o pacote:&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;dotnet&lt;/span&gt; &lt;span class="k"&gt;add&lt;/span&gt; &lt;span class="n"&gt;package&lt;/span&gt; &lt;span class="n"&gt;examplePackage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Convert&lt;/span&gt; &lt;span class="p"&gt;--&lt;/span&gt;&lt;span class="n"&gt;version&lt;/span&gt; &lt;span class="m"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Testando o Pacote
&lt;/h2&gt;

&lt;p&gt;Abra o arquivo &lt;strong&gt;Program.cs&lt;/strong&gt; do projeto de teste e use o pacote:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Friirfv6wsay6rkoz3tdq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Friirfv6wsay6rkoz3tdq.png" alt="Importando pacote da fonte local" width="799" height="243"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd123n0bvkc5mmi2jmw01.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd123n0bvkc5mmi2jmw01.png" alt="Utilizando pacote da fonte local" width="800" height="219"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Publicação
&lt;/h2&gt;

&lt;p&gt;Após validar seu pacote, é hora de publicá-lo. Acesse sua conta em &lt;a href="https://www.nuget.org/" rel="noopener noreferrer"&gt;NuGet.org&lt;/a&gt;, vá até o seu perfil e crie uma nova chave.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpvjfb3ozoz75bqijmmrd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpvjfb3ozoz75bqijmmrd.png" alt="Gerando chave para publicação de pacotes" width="800" height="687"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No terminal, use o comando abaixo para publicar seu pacote no NuGet:&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;dotnet&lt;/span&gt; &lt;span class="n"&gt;nuget&lt;/span&gt; &lt;span class="n"&gt;push&lt;/span&gt; &lt;span class="n"&gt;bin&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;Release&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;examplePackage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Convert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="m"&gt;1.0&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="n"&gt;nupkg&lt;/span&gt; &lt;span class="p"&gt;--&lt;/span&gt;&lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="n"&gt;SuaAPIkEY&lt;/span&gt; &lt;span class="p"&gt;--&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="n"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//api.nuget.org/v3/index.json&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pronto, se tudo estiver correto após alguns minutos, o pacote estará disponível no &lt;a href="http://nuget.org/" rel="noopener noreferrer"&gt;NuGet.org&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2ptnm395so7h1w2g567d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2ptnm395so7h1w2g567d.png" alt="Pacote publicado" width="800" height="410"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Agora que você aprendeu a criar, testar e publicar pacotes NuGet, pode começar a criar os seus próprios pacotes para facilitar o seu trabalho e, quem sabe, ajudar outras pessoas com as suas soluções.&lt;/p&gt;

&lt;h2&gt;
  
  
  Materiais Relacionados e Referências
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/nuget/what-is-nuget" rel="noopener noreferrer"&gt;NuGet: Introdução&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/nuget/reference/nuspec" rel="noopener noreferrer"&gt;Referência do .nuspec&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/en-us/nuget/create-packages/publish-a-package" rel="noopener noreferrer"&gt;Publicando Pacotes no NuGet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://semver.org/" rel="noopener noreferrer"&gt;SemVer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://abhishek-ankush.medium.com/creating-custom-nuget-package-in-c-f620c3c67cd8" rel="noopener noreferrer"&gt;Creating Custom NuGet Package in C#&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.treinaweb.com.br/blog/o-que-e-o-nuget" rel="noopener noreferrer"&gt;O que é o NuGet? | Blog da TreinaWeb&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=E0rPteTWxYQ&amp;amp;ab_channel=dotnet" rel="noopener noreferrer"&gt;Creating and Publishing a NuGet Package [Pt 3] | NuGet for Beginners&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>csharp</category>
      <category>nuget</category>
      <category>dotnet</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Como Definir o Contexto Adequado ao Construir um Dockerfile</title>
      <dc:creator>Gabriel Batista</dc:creator>
      <pubDate>Thu, 05 Oct 2023 05:15:30 +0000</pubDate>
      <link>https://dev.to/devgabrielb/como-definir-o-contexto-adequado-ao-construir-um-dockerfile-1ee4</link>
      <guid>https://dev.to/devgabrielb/como-definir-o-contexto-adequado-ao-construir-um-dockerfile-1ee4</guid>
      <description>&lt;p&gt;Quantas vezes você já se deparou com a situação em que tentou criar um Dockerfile e, de repente, ele não conseguia copiar os arquivos para o container? A razão por trás disso pode estar relacionada à escolha do contexto adequado.&lt;/p&gt;

&lt;p&gt;Quando trabalhamos com Dockerfiles, é fundamental entender que o Docker utiliza um diretório como ponto de partida inicial para a construção da imagem. Isso significa que apenas os arquivos presentes nesse diretório e seus subdiretórios são acessíveis durante o processo de build. &lt;/p&gt;

&lt;p&gt;Por exemplo, considere a seguinte estrutura de diretórios:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;├ exemplo dockerfile
│   ├── docker
│   │   ├── Dockerfile
│   │   └── .dockerignore
│   └── package.json
│   └── server.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dockerfile:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM node:18

# Create app directory

WORKDIR /app

COPY package*.json ./

RUN npm install

COPY . .

EXPOSE 8080

CMD [ "node", "server.js" ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se tentarmos executar o comando de build a partir do diretório &lt;code&gt;docker&lt;/code&gt;, como o exemplo a seguir:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker build -t image/teste .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nos deparamos com o seguinte erro:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmipgwccad9kyiumdwlqe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmipgwccad9kyiumdwlqe.png" alt="error docker build" width="800" height="421"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Esse erro ocorre devido a incapacidade do Docker de localizar os arquivos desejados, uma vez que o contexto atual, ou seja, o diretório &lt;code&gt;docker&lt;/code&gt;, não inclui o diretório pai que contém os arquivos relevantes.&lt;/p&gt;

&lt;p&gt;Então, qual é a solução?&lt;/p&gt;

&lt;p&gt;Para garantir que a compilação seja bem-sucedida, é crucial ampliar o contexto de construção. Em vez de executar o comando de build a partir do diretório &lt;code&gt;docker&lt;/code&gt;, você deve retornar à raiz do projeto e, em seguida, utilizar o seguinte comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker build -f docker/Dockerfile -t image/teste .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vamos analisar cada componente desse comando:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;docker build:&lt;/strong&gt; Este é o comando que dá início ao processo de construção da imagem Docker.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;-f docker/Dockerfile:&lt;/strong&gt; Especifica o arquivo Dockerfile a ser usado para construir a imagem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;-t image/teste:&lt;/strong&gt; Essa opção define um nome (ou uma "tag") para a imagem que será criada.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;".":&lt;/strong&gt; O ponto no final do comando indica o contexto de construção, ou seja, o diretório no qual o Docker procurará o Dockerfile e quaisquer outros arquivos necessários para a construção da imagem. O ponto representa o diretório atual.&lt;/p&gt;

&lt;p&gt;Após a execução bem-sucedida dessa instrução, você pode esperar o seguinte resultado:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl9ca9qgrmm4btwyc3v2q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl9ca9qgrmm4btwyc3v2q.png" alt="docker build success" width="800" height="209"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Com essa abordagem, você consegue especificar qual Dockerfile deseja utilizar e também indicar qual é o contexto. O ponto "." representa a raiz do projeto e instrui o Docker a considerar esse ponto como o contexto inicial para a construção da imagem.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>tutorial</category>
      <category>programming</category>
      <category>node</category>
    </item>
  </channel>
</rss>
