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 diamante no gráfico de dependência do aplicativo.

Diamond dependency

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 de quebra 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. São necessários redirecionamentos de vinculação de montagem.

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 de quebra possam ter sido introduzidas na versão 2.0, uma dependência de versão estrita ou limite superior garante um erro.

Diamond dependency conflict

❌ NÃO tem 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 Controle de versão 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.

Shared source package

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

Shared source project

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.

✔️ Fazer referência a pacotes de código-fonte compartilhados com PrivateAssets="All"o .

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 compartilhada são compilados no assembly de referência e não podem ser trocados entre os limites do assembly. 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 compartilhados devem ter uma internal visibilidade.

❌ 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.