Gerenciamento Central de Pacotes (CPM)
O gerenciamento de dependência é um recurso central do NuGet. Gerenciar dependências para um único projeto pode ser fácil. Gerenciar dependências para soluções de vários projetos pode ser difícil à medida que elas começam a ser dimensionadas em tamanho e complexidade. Em situações em que você gerencia dependências comuns para muitos projetos diferentes, pode aproveitar os recursos de gerenciamento central de pacotes (CPM) do NuGet para fazer tudo isso com a facilidade de um único local.
Historicamente, as dependências do pacote NuGet eram gerenciadas em um de dois locais:
-
packages.config
- Um arquivo XML usado em tipos de projeto mais antigos para manter a lista de pacotes referenciados pelo projeto. -
<PackageReference />
- Um elemento XML usado em projetos MSBuild define as dependências do pacote NuGet.
A partir do NuGet 6.2, você pode gerenciar centralmente suas dependências em seus projetos com a adição de um arquivo Directory.Packages.props
e uma propriedade MSBuild.
O recurso está disponível em todas as ferramentas integradas do NuGet, começando com as versões a seguir.
As ferramentas mais antigas ignorarão as configurações e os recursos do gerenciamento central de pacotes. Para usar esse recurso ao máximo, certifique-se de que todos os seus ambientes de compilação usem as versões mais recentes de ferramentas compatíveis.
O gerenciamento central de pacotes aplica-se a todos os projetos MSBuild baseados em <PackageReference>
(incluindo CSPROJ herdado) desde que ferramentas compatíveis sejam usadas.
Habilitando o gerenciamento central de pacotes
Para começar com o gerenciamento central de pacotes, você deve criar um arquivo de Directory.Packages.props
na raiz do repositório e definir a propriedade MSBuild ManagePackageVersionsCentrally
como true
.
Você pode criá-lo manualmente ou você pode usar a CLI dotnet:
dotnet new packagesprops
No interior, você define cada uma das respetivas versões de pacote necessárias dos seus projetos, usando elementos <PackageVersion />
que definem o ID e a versão do pacote.
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Newtonsoft.Json" Version="13.0.1" />
</ItemGroup>
</Project>
Para cada projeto, você define um <PackageReference />
mas omite o atributo Version
, pois a versão será obtida a partir de um item de <PackageVersion />
correspondente.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" />
</ItemGroup>
</Project>
Agora você está usando o gerenciamento central de pacotes e gerenciando suas versões em um local central!
Regras de gerenciamento de pacotes centrais
O arquivo Directory.Packages.props
tem uma série de regras com relação a onde ele está localizado no diretório de um repositório e seu contexto. Por uma questão de simplicidade, apenas um arquivo Directory.Packages.props
é avaliado para um determinado projeto.
Isso significa que, se você tiver vários arquivos Directory.Packages.props
em seu repositório, o arquivo mais próximo do diretório do seu projeto será avaliado para ele. Isso permite um controle extra em vários níveis do seu repositório.
Aqui está um exemplo, considere a seguinte estrutura de repositório:
Repository
|-- Directory.Packages.props
|-- Solution1
|-- Directory.Packages.props
|-- Project1
|-- Solution2
|-- Project2
- Project1 avaliará o arquivo
Directory.Packages.props
no diretórioRepository\Solution1\
e deverá importar manualmente o próximo, se assim desejar.<Project> <Import Project="$([MSBuild]::GetPathOfFileAbove(Directory.Packages.props, $(MSBuildThisFileDirectory)..))" /> <ItemGroup> <PackageVersion Update="Newtonsoft.Json" Version="12.0.1" /> </ItemGroup> </Project>
- O Project2 avaliará o arquivo
Directory.Packages.props
no diretórioRepository\
.
Nota: MSBuild não importará automaticamente cada Directory.Packages.props
para você, apenas o primeiro mais próximo do projeto. Se tiveres vários Directory.Packages.props
, deverás importar o elemento pai manualmente, enquanto que o Directory.Packages.props
raiz não precisaria ser.
Começar
Para integrar totalmente seu repositório, considere seguir estas etapas:
- Crie um novo arquivo na raiz do repositório chamado
Directory.Packages.props
que declare suas versões de pacote definidas centralmente e defina a propriedade MSBuildManagePackageVersionsCentrally
comotrue
. - Declare
<PackageVersion />
itens no seuDirectory.Packages.props
. - Declare
<PackageReference />
itens semVersion
atributos em seus arquivos de projeto.
Para ter uma ideia de como pode ser o gerenciamento central de pacotes, consulte o nosso repositório de amostras em.
Fixação transitiva
Você pode substituir automaticamente uma versão transitiva do pacote, mesmo sem um <PackageReference />
de nível superior explícito, optando por um recurso conhecido como fixação transitiva. Isso promove uma dependência transitiva para uma dependência de nível superior implicitamente em seu nome, quando necessário.
Note que os rebaixamentos são permitidos ao fixar transitarmente um pacote. Se tu tentares fixar um pacote numa versão inferior à solicitada pelas tuas dependências, a restauração levantará um erro NU1109.
Você pode habilitar esse recurso definindo a propriedade MSBuild CentralPackageTransitivePinningEnabled
para true
em um projeto ou em um arquivo de importação Directory.Packages.props
ou Directory.Build.props
:
<PropertyGroup>
<CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
</PropertyGroup>
Fixação transitiva e embalagem
Quando um pacote é bloqueado transitoriamente, o seu projeto usa uma versão superior à solicitada por suas dependências. Se você criar um pacote a partir do seu projeto, para garantir que seu pacote funcione, o NuGet promoverá as dependências fixadas transitivamente para dependências explícitas no nuspec.
No exemplo a seguir, PackageA 1.0.0
tem uma dependência de PackageB 1.0.0
.
<Project>
<ItemGroup>
<PackageVersion Include="PackageA" Version="1.0.0" />
<PackageVersion Include="PackageB" Version="2.0.0" />
</ItemGroup>
</Project>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="PackageA" />
</ItemGroup>
</Project>
Quando você usa o comando pack para criar um pacote, ambos os pacotes aparecerão no grupo de dependência.
<group targetFramework="net6.0">
<dependency id="PackageA" version="1.0.0" exclude="Build,Analyzers" />
<dependency id="PackageB" version="2.0.0" exclude="Build,Analyzers" />
</group>
Por isso, o uso da fixação transitiva deve ser cuidadosamente avaliado ao criar uma biblioteca, pois pode resultar em dependências que o utilizador não esperava.
Sobrescrevendo versões de pacotes
Você pode substituir uma versão de pacote individual usando a propriedade VersionOverride
em um item <PackageReference />
. Isso substitui qualquer <PackageVersion />
definido centralmente.
<Project>
<ItemGroup>
<PackageVersion Include="PackageA" Version="1.0.0" />
<PackageVersion Include="PackageB" Version="2.0.0" />
</ItemGroup>
</Project>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="PackageA" VersionOverride="3.0.0" />
</ItemGroup>
</Project>
Você pode desabilitar esse recurso definindo a propriedade MSBuild CentralPackageVersionOverrideEnabled
para false
em um projeto ou em um arquivo de importação Directory.Packages.props
ou Directory.Build.props
:
<PropertyGroup>
<CentralPackageVersionOverrideEnabled>false</CentralPackageVersionOverrideEnabled>
</PropertyGroup>
Quando esse recurso é desativado, especificar uma VersionOverride
em qualquer item de <PackageReference />
resultará em um erro no momento da restauração indicando que o recurso está desativado.
Desativando o Gerenciamento Central de Pacotes
Se você quiser desabilitar o gerenciamento central de pacotes para qualquer projeto específico, você pode desativá-lo definindo a propriedade MSBuild ManagePackageVersionsCentrally
para false
:
<PropertyGroup>
<ManagePackageVersionsCentrally>false</ManagePackageVersionsCentrally>
</PropertyGroup>
Referências de pacotes globais
Observação
Esse recurso só está disponível no Visual Studio 2022 17.4 ou superior, no .NET SDK 7.0.100.preview7 ou superior e no NuGet 6.4 ou superior.
Uma referência de pacote global é usada para especificar que um pacote será usado por cada projeto em um repositório. Isso inclui pacotes que fazem versionamento, estendem sua compilação ou quaisquer outros pacotes que são necessários para todos os projetos. As referências de pacote global são adicionadas ao grupo de itens PackageReference com os seguintes metadados:
IncludeAssets="Runtime;Build;Native;contentFiles;Analyzers"
Isso garante que o pacote seja usado apenas como uma dependência de desenvolvimento e impede quaisquer referências de assembly em tempo de compilação.PrivateAssets="All"
Isso impede que as referências de pacotes globais sejam utilizadas por dependências posteriores.
GlobalPackageReference
itens devem ser colocados no seu Directory.Packages.props
para serem usados por todos os projetos num repositório:
<Project>
<ItemGroup>
<GlobalPackageReference Include="Nerdbank.GitVersioning" Version="3.5.109" />
</ItemGroup>
</Project>
Aviso ao usar várias fontes de pacote
Ao usar o gerenciamento central de pacotes, você verá um aviso de NU1507
se tiver mais de uma fonte de pacote definida em sua configuração. Para resolver esse aviso, mapeie as fontes de pacote com de mapeamento de origem de pacote ou especifique uma única fonte de pacote.
There are 3 package sources defined in your configuration. When using central package management, please map your package sources with package source mapping (https://aka.ms/nuget-package-source-mapping) or specify a single package source.
Observação
O gerenciamento central de pacotes está em desenvolvimento ativo. Agradecemos que você experimente e forneça qualquer feedback que possa ter em NuGet/Home.