DependênciasDependencies

A principal maneira de adicionar as dependências em uma biblioteca do .NET fazer referência a pacotes do NuGet.The primary way of adding dependencies to a .NET library is referencing NuGet packages. Referências de pacote do NuGet permitem que você rapidamente reutilize e aproveite a funcionalidade já escrita, mas são uma fonte comum de atrito para desenvolvedores do .NET.NuGet package references allow you to quickly reuse and leverage already written functionality, but they're a common source of friction for .NET developers. Gerenciar dependências corretamente é importante para evitar que alterações em outras bibliotecas .NET provoquem falhas na sua biblioteca do .NET e vice-versa.Correctly managing dependencies is important to prevent changes in other .NET libraries from breaking your .NET library, and vice versa!

Dependências de losangoDiamond dependencies

É uma situação comum um projeto do .NET ter várias versões de um pacote em sua árvore de dependência.It's a common situation for a .NET project to have multiple versions of a package in its dependency tree. Por exemplo, um aplicativo depende de dois pacotes do NuGet e cada um dos quais depende de versões diferentes do mesmo pacote.For example, an app depends on two NuGet packages, each of which depends on different versions of the same package. Agora existe uma dependência de losango no grafo de dependência do aplicativo.A diamond dependency now exists in the app's dependency graph.

Dependência de losangoDiamond dependency

No momento da compilação, o NuGet analisa todos os pacotes de que um projeto depende, incluindo as dependências das dependências.At build time, NuGet analyzes all the packages that a project depends on, including the dependencies of dependencies. Quando várias versões de um pacote são detectadas, as regras são avaliadas para escolher uma.When multiple versions of a package are detected, rules are evaluated to pick one. Unificar pacotes é necessário porque executar versões lado a lado de um assembly no mesmo aplicativo é um problema no .NET.Unifying packages is necessary because running side-by-side versions of an assembly in the same application is problematic in .NET.

A maioria das dependências de losangos é facilmente resolvida. No entanto, podem criar problemas em determinadas circunstâncias:Most diamond dependencies are easily resolved; however, they can create issues in certain circumstances:

  • Referências de pacote do NuGet conflitantes impedem que uma versão seja resolvida durante a restauração de pacote.Conflicting NuGet package references prevent a version from being resolved during package restore.
  • Alterações interruptivas entre as versões causam erros e exceções em tempo de execução.Breaking changes between the versions cause bugs and exceptions at run time.
  • O assembly do pacote tem um nome forte, a versão do assembly foi alterada e o aplicativo está sendo executado em .NET Framework.The package assembly is strong named, the assembly version changed, and the app is running on .NET Framework. Redirecionamentos de associação de assembly são necessários.Assembly binding redirects are required.

Não é possível saber quais pacotes serão usados junto com o seu.It's not possible to know what packages will be used alongside your own. Uma boa maneira de reduzir a probabilidade de uma dependência de losango provocar falha na sua biblioteca é minimizar o número de pacotes dos quais você depende.A good way to reduce the likelihood of a diamond dependency breaking your library is to minimize the number of packages you depend on.

✔️ FAÇA a análise da sua biblioteca do .NET quanto a dependências desnecessárias.✔️ DO review your .NET library for unnecessary dependencies.

Intervalos de versão de dependência do NuGetNuGet dependency version ranges

Uma referência de pacote especifica o intervalo de pacotes válidos que ela permite.A package reference specifies the range of valid packages it allows. Normalmente, a versão de referência de pacote no arquivo de projeto é a versão mínima e não há um máximo.Typically, the package reference version in the project file is the minimum version and there's no maximum.

<!-- 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 mais baixa aplicável.The rules that NuGet uses when resolving dependencies are complex, but NuGet by default looks for the lowest applicable version. O NuGet prefere a versão mais antiga aplicável, em vez de usar a mais alta disponível, porque a mais baixa terá menos problemas de compatibilidade.NuGet prefers the lowest applicable version over using the highest available because the lowest will have the least compatibility issues.

Devido à regra de versão mais baixa aplicável do NuGet, não é necessário colocar uma versão superior ou o intervalo exato em referências de pacote para evitar obter a versão mais recente.Because of NuGet's lowest applicable version rule, it isn't necessary to place an upper version or exact range on package references to avoid getting the latest version. O NuGet já tenta encontrar a versão mais baixa e mais compatível para você.NuGet already tries to find the lowest, most compatible version for you.

<!-- 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]" />

Limites de versão superior fará com que o NuGet falhe se houver um conflito.Upper version limits will cause NuGet to fail if there's a conflict. Por exemplo, uma biblioteca aceita exatamente 1.0, enquanto a outra biblioteca exige 2.0 ou superior.For example, one library accepts exactly 1.0 while another library requires 2.0 or above. Embora alterações da falha possam ter sido introduzidas na versão 2.0, uma dependência de versão do limite superior ou estrita garantirá um erro.While breaking changes may have been introduced in version 2.0, a strict or upper limit version dependency guarantees an error.

Conflito de dependência de losangoDiamond dependency conflict

❌ Não tem referências de pacote NuGet sem nenhuma versão mínima.❌ DO NOT have NuGet package references with no minimum version.

❌ Evite as referências de pacote NuGet que exigem uma versão exata.❌ AVOID NuGet package references that demand an exact version.

❌ Evite as referências de pacote NuGet com um limite superior de versão.❌ AVOID NuGet package references with a version upper limit.

Pacotes de código-fonte compartilhado do NuGetNuGet shared source packages

Uma maneira de reduzir as dependências externas do pacote NuGet é fazer referência a pacotes de origem compartilhados.One way to reduce external NuGet package dependencies is to reference shared source packages. Um pacote de origem compartilhado contém arquivos de código-fonte incluídos em um projeto quando referenciados.A shared source package contains source code files that are included in a project when referenced. Como você está apenas incluindo arquivos de código-fonte compilados com o restante do seu projeto, não há dependência externa nem chance de conflito.Because you're just including source code files that are compiled with the rest of your project, there's no external dependency and chance of conflict.

Pacotes de origem compartilhados são ótimos para incluir pequenas funcionalidades.Shared source packages are great for including small pieces of functionality. Por exemplo, um pacote origem compartilhado de métodos auxiliares para fazer chamadas HTTP.For example, a shared source package of helper methods for making HTTP calls.

Pacote de origem compartilhadoShared source package

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

Projeto de origem compartilhadoShared source project

Pacotes de origem compartilhado têm algumas limitações.Shared source packages have some limitations. Eles só podem ser referenciados por PackageReference, portanto, projetos packages.config mais antigos são excluídos.They can only be referenced by PackageReference, so older packages.config projects are excluded. Também pacotes de origem compartilhados somente são utilizáveis por projetos com o mesmo tipo de linguagem.Also shared source packages are only usable by projects with the same language type. Devido a essas limitações, pacotes de origem compartilhados são melhor usados para compartilhar a funcionalidade dentro de um projeto de código-fonte aberto.Because of these limitations shared source packages are best used to share functionality within an open-source project.

✔️ CONSIDERE fazer referência a de código-fonte compartilhados para pequenas funcionalidades internas.✔️ CONSIDER referencing shared source packages for small, internal pieces of functionality.

✔️ CONSIDERE tornar seu pacote de um pacote de origem compartilhado se ele oferecer pequenas funcionalidades internas.✔️ CONSIDER making your package a shared source package if it provides small, internal pieces of functionality.

✔️ FAÇA referência a pacotes de origem compartilhados com PrivateAssets="All".✔️ DO reference shared source packages with PrivateAssets="All".

Essa configuração informa que o pacote do NuGet deve ser usado apenas no tempo de desenvolvimento e não deve ser exposto como uma dependência pública.This setting tells NuGet the package is only to be used at development time and shouldn't be exposed as a public dependency.

❌ Não têm tipos de pacote de origem compartilhados em sua API pública.❌ DO NOT have shared source package types in your public API.

Tipos de origem compartilhada são compilados no assembly de referência e não podem ser trocados entre os limites de assembly.Shared source types are compiled into the referencing assembly and can't be exchanged across assembly boundaries. Por exemplo, um tipo IRepository de origem compartilhada em um projeto é um tipo separado do mesmo IRepository de origem compartilhada em outro projeto.For example, a shared-source IRepository type in one project is a separate type from the same shared-source IRepository in another project. Tipos em pacotes de origem compartilhados devem ter uma visibilidade internal.Types in shared source packages should have an internal visibility.

❌ Não publique pacotes de origem compartilhados em NuGet.org.❌ DO NOT publish shared source packages to NuGet.org.

Pacotes de origem compartilhados contêm código-fonte e só podem ser usados por projetos com o mesmo tipo de linguagem.Shared source packages contain source code and can only be used by projects with the same language type. Por exemplo, um pacote de origem compartilhado em C# não pode ser usado por um aplicativo em F#.For example, a C# shared source package cannot be used by an F# application.

Publicar pacotes de origem compartilhados em um feed local ou no MyGet para consumi-los internamente dentro de seu projeto.Publish shared source packages to a local feed or MyGet to consume them internally within your project.