Partilhar via


Dependências

A principal maneira de adicionar dependências a uma biblioteca .NET é fazer referência a pacotes NuGet. As referências de pacote NuGet permitem que você reutilize rapidamente e aproveite a funcionalidade já escrita, mas elas são uma fonte comum de atrito para desenvolvedores .NET. O gerenciamento correto de dependências é importante para evitar que alterações em outras bibliotecas .NET quebrem sua biblioteca .NET e vice-versa!

Dependências diamantadas

É comum que um projeto .NET tenha várias versões de um pacote em sua árvore de dependência. Por exemplo, um aplicativo depende de dois pacotes NuGet, cada um dos quais depende de uma versão diferente do mesmo pacote. Agora existe uma dependência em forma de diamante no gráfico de dependências da aplicação.

Dependência de diamantes

No momento da compilação, o NuGet analisa todos os pacotes dos quais um projeto depende, incluindo as dependências das dependências. Quando várias versões de um pacote são detetadas, as regras são avaliadas para escolher uma. A unificação de pacotes é necessária porque a execução de versões lado a lado de um assembly no mesmo aplicativo é problemática no .NET.

A maioria das dependências de diamantes são facilmente resolvidas; No entanto, podem criar problemas em determinadas circunstâncias:

  • Referências de pacote NuGet conflitantes impedem que uma versão seja resolvida durante a restauração do pacote.
  • Alterações incompatíveis entre as versões causam bugs e exceções em tempo de execução.
  • O assembly do pacote tem um nome forte, a versão do assembly foi alterada e o aplicativo está sendo executado no .NET Framework. Os redirecionamentos de ligação de montagem são necessários.

Não é possível saber quais pacotes serão usados ao lado dos seus. Uma boa maneira de reduzir a probabilidade de uma dependência de diamante quebrar sua biblioteca é minimizar o número de pacotes dos quais você depende.

✔️ REVISE sua biblioteca .NET para verificar se há dependências desnecessárias.

Intervalos de versões de dependência do NuGet

Uma referência de pacote especifica o intervalo de pacotes válidos permitidos. Normalmente, a versão de referência do pacote no arquivo de projeto é a versão mínima e não há máxima.

<!-- Accepts any version 1.0 and above. -->
<PackageReference Include="ExamplePackage" Version="1.0" />

As regras que o NuGet usa ao resolver dependências são complexas, mas o NuGet por padrão procura a versão aplicável mais baixa. O NuGet prefere a versão mais baixa aplicável em vez de usar a mais alta disponível, porque a mais baixa terá menos problemas de compatibilidade.

Devido à regra de versão aplicável mais baixa do NuGet, não é necessário colocar uma versão superior ou um intervalo exato nas referências do pacote para evitar obter a versão mais recente. O NuGet já tenta encontrar a versão mais baixa e compatível para você.

<!-- Accepts 1.0 up to 1.x, but not 2.0 and higher. -->
<PackageReference Include="ExamplePackage" Version="[1.0,2.0)" />

<!-- Accepts exactly 1.0. -->
<PackageReference Include="ExamplePackage" Version="[1.0]" />

Os limites de versão superior farão com que o NuGet falhe se houver um conflito. Por exemplo, uma biblioteca aceita exatamente 1.0 enquanto outra biblioteca requer 2.0 ou superior. Embora alterações disruptivas possam ter sido introduzidas na versão 2.0, uma dependência de versão estrita ou limitação superior garante um erro.

Conflito de dependência dos diamantes

❌ NÃO DEVE ter referências de pacote NuGet sem versão mínima.

❌ EVITE referências de pacotes NuGet que exijam uma versão exata.

❌ EVITE referências de pacotes NuGet com um limite superior de versão.

Para obter mais informações, consulte Versionamento de pacotes.

Pacotes de código-fonte compartilhados do NuGet

Uma maneira de reduzir as dependências externas do pacote NuGet é fazer referência a pacotes de origem compartilhados. Um pacote de código-fonte compartilhado contém arquivos de código-fonte que são incluídos em um projeto quando referenciados. Como você está apenas incluindo arquivos de código-fonte que são compilados com o resto do projeto, não há dependência externa e chance de conflito.

Os pacotes de código-fonte compartilhados são ótimos para incluir pequenas partes de funcionalidade. Por exemplo, você pode fazer referência a um pacote de código-fonte compartilhado de métodos auxiliares para fazer chamadas HTTP.

Pacote de código-fonte compartilhado

<PackageReference Include="Microsoft.Extensions.Buffers.Testing.Sources" PrivateAssets="All" Version="1.0" />

Projeto de código-fonte compartilhado

Os pacotes de código-fonte compartilhados têm algumas limitações. Só podem ser referenciados pela PackageReference, pelo que os projetos mais antigos packages.config são excluídos. Além disso, pacotes de código-fonte compartilhados só são utilizáveis por projetos com a mesma linguagem. Devido a essas limitações, os pacotes de código-fonte compartilhados são melhor usados para compartilhar a funcionalidade dentro de um projeto de código aberto.

✔️ CONSIDERE fazer referência a pacotes de código-fonte compartilhados para pequenas partes internas de funcionalidade.

✔️ CONSIDERE tornar seu pacote um pacote de código-fonte compartilhado se ele fornecer pequenas partes internas de funcionalidade.

✔️ Referenciar pacotes de código-fonte compartilhados com PrivateAssets="All".

Essa configuração informa ao NuGet que o pacote deve ser usado apenas no momento do desenvolvimento e não deve ser exposto como uma dependência pública.

❌ NÃO tenha tipos de pacotes de código-fonte compartilhados em sua API pública.

Os tipos de origem partilhada são compilados na assembleia de referência e não podem ser trocados entre os limites da assembleia. Por exemplo, um tipo de fonte IRepository compartilhada em um projeto é um tipo separado da mesma fonte IRepository compartilhada em outro projeto. Os tipos em pacotes de código-fonte partilhados devem ter uma visibilidade internal.

❌ NÃO publique pacotes de código-fonte compartilhados para NuGet.org.

Os pacotes de código-fonte compartilhados contêm código-fonte e só podem ser usados por projetos com o mesmo tipo de linguagem. Por exemplo, um pacote de código-fonte compartilhado C# não pode ser usado por um aplicativo F#.

Publique pacotes de código-fonte compartilhados em um feed local ou MyGet para consumi-los internamente em seu projeto.