Compartir a través de


Administración central de paquetes (CPM)

La administración de dependencias es una característica principal de NuGet. La administración de dependencias para un solo proyecto puede ser fácil. La administración de dependencias para soluciones de varios proyectos puede resultar difícil a medida que empiezan a escalar en tamaño y complejidad. En situaciones en las que se administran dependencias comunes para muchos proyectos diferentes, puede aprovechar las características de administración de paquetes centrales (CPM) de NuGet para hacer todo esto desde la facilidad de una sola ubicación.

Históricamente, las dependencias del paquete NuGet se han administrado en una de estas dos ubicaciones:

  • packages.config: archivo XML usado en tipos de proyecto más antiguos para mantener la lista de paquetes a los que hace referencia el proyecto.
  • <PackageReference />: un elemento XML usado en proyectos de MSBuild define las dependencias del paquete NuGet.

A partir de nuGet 6.2, puede administrar de forma centralizada las dependencias de los proyectos con la adición de un archivo Directory.Packages.props y una propiedad de MSBuild.

La característica está disponible en todas las herramientas integradas de NuGet, empezando por las siguientes versiones.

Las herramientas anteriores omitirán las configuraciones y características de administración de paquetes centrales. Para usar esta característica en la medida más completa, asegúrese de que todos los entornos de compilación usen las versiones de herramientas compatibles más recientes.

La administración central de paquetes se aplica a todos los proyectos de MSBuild basados en <PackageReference>(incluido CSPROJ heredado) siempre que se usen herramientas compatibles.

Habilitación de la administración central de paquetes

Para empezar a trabajar con la administración central de paquetes, debe crear un archivo Directory.Packages.props en la raíz del repositorio y establecer la propiedad de MSBuild ManagePackageVersionsCentrally en true.

Puede crearlo manualmente o puede usar la CLI de dotnet:

dotnet new packagesprops

A continuación, definirá cada una de las versiones de paquete correspondientes necesarias para sus proyectos mediante los elementos <PackageVersion /> que definen el identificador y la versión del paquete.

<Project>
  <PropertyGroup>
    <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
  </PropertyGroup>
  <ItemGroup>
    <PackageVersion Include="Newtonsoft.Json" Version="13.0.1" />
  </ItemGroup>
</Project>

Para cada proyecto, se define un <PackageReference /> pero se omite el atributo Version, ya que la versión se obtendrá de un elemento de <PackageVersion /> correspondiente.

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Newtonsoft.Json" />
  </ItemGroup>
</Project>

Ahora usa la administración central de paquetes y administra las versiones en una ubicación central.

Reglas de administración de paquetes centrales

El archivo Directory.Packages.props tiene una serie de reglas con respecto a dónde se encuentra en el directorio de un repositorio y su contexto. Por motivos de simplicidad, solo se evalúa un archivo Directory.Packages.props para un proyecto determinado.

Esto significa que si tenía varios archivos de Directory.Packages.props en el repositorio, se evaluará el archivo más cercano al directorio del proyecto. Esto permite un control adicional en varios niveles del repositorio.

Este es un ejemplo, considere la siguiente estructura de repositorio:

Repository
 |-- Directory.Packages.props
 |-- Solution1
     |-- Directory.Packages.props
     |-- Project1
 |-- Solution2
     |-- Project2
  • Project1 evaluará el archivo Directory.Packages.props en el directorio Repository\Solution1\ y debe importar manualmente el siguiente si así lo desea.
    <Project>
      <Import Project="$([MSBuild]::GetPathOfFileAbove(Directory.Packages.props, $(MSBuildThisFileDirectory)..))" />
      <ItemGroup>
        <PackageVersion Update="Newtonsoft.Json" Version="12.0.1" />
      </ItemGroup>
    </Project>
    
  • Project2 evaluará el archivo Directory.Packages.props en el directorio Repository\.

Nota: MSBuild no importará automáticamente cada Directory.Packages.props, solo la primera más cercana al proyecto. Si tiene varias Directory.Packages.props, debe importar la parental manualmente, mientras que la raíz Directory.Packages.props no lo haría.

Comenzar

Para incorporar completamente el repositorio, considere la posibilidad de realizar estos pasos:

  1. Cree un nuevo archivo en la raíz del repositorio denominado Directory.Packages.props que declare las versiones del paquete definidas centralmente y establezca la propiedad MSBuild ManagePackageVersionsCentrally en true.
  2. Declarar <PackageVersion /> elementos en el Directory.Packages.props.
  3. Declare elementos <PackageReference /> sin atributos Version en los archivos del proyecto.

Para obtener una idea del aspecto de la administración central de paquetes, consulte nuestro repositorio de ejemplos de .

Anclaje transitivo

Puede invalidar automáticamente una versión de paquete transitiva incluso sin un <PackageReference /> de nivel superior explícito si opta por una característica conocida como anclaje transitivo. Esto promueve una dependencia transitiva a una dependencia de nivel superior implícitamente en su nombre cuando sea necesario. Tenga en cuenta que se permiten degradaciones al anclar un paquete transitivo. Si intenta anclar un paquete a una versión inferior a la solicitada por las dependencias, la restauración generará un error de NU1109.

Puede habilitar esta característica estableciendo la propiedad MSBuild CentralPackageTransitivePinningEnabled en true en un proyecto o en un archivo de importación de Directory.Packages.props o Directory.Build.props:

<PropertyGroup>
  <CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
</PropertyGroup>

Anclaje y empaquetado transitivo

Cuando un paquete está anclado de forma transitiva, tu proyecto usa una versión superior a la solicitada por tus dependencias. Si crea un paquete a partir del proyecto, para asegurarse de que el paquete funcionará, NuGet promoverá las dependencias ancladas transitivamente a dependencias explícitas en el Nuspec.

En el ejemplo siguiente, PackageA 1.0.0 tiene una dependencia 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>

Al usar el comando pack para crear un paquete, ambos paquetes aparecerán en el grupo de dependencias.

      <group targetFramework="net6.0">
        <dependency id="PackageA" version="6.12.1" exclude="Build,Analyzers" />
        <dependency id="PackageB" version="6.12.1" exclude="Build,Analyzers" />
      </group>

Debido a esto, el uso del anclaje transitivo debe evaluarse cuidadosamente al desarrollar una biblioteca, ya que podría causar dependencias inesperadas.

Invalidación de versiones de paquete

Puede invalidar una versión de paquete individual mediante la propiedad VersionOverride en un elemento de <PackageReference />. Esto invalida cualquier <PackageVersion /> definida 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>

Puede deshabilitar esta característica estableciendo la propiedad MSBuild CentralPackageVersionOverrideEnabled en false en un proyecto o en un archivo de importación de Directory.Packages.props o Directory.Build.props:

<PropertyGroup>
  <CentralPackageVersionOverrideEnabled>false</CentralPackageVersionOverrideEnabled>
</PropertyGroup>

Cuando esta característica está deshabilitada, especificar un VersionOverride en cualquier elemento de <PackageReference /> producirá un error en el momento de la restauración que indica que la característica está deshabilitada.

Deshabilitación de la administración central de paquetes

Si desea deshabilitar la administración central de paquetes para cualquier proyecto determinado, puede deshabilitarla estableciendo la propiedad de MSBuild ManagePackageVersionsCentrally en false:

<PropertyGroup>
  <ManagePackageVersionsCentrally>false</ManagePackageVersionsCentrally>
</PropertyGroup>

Referencias de paquetes globales

Nota

Esta característica solo está disponible en Visual Studio 2022 17.4 o posterior, sdk de .NET 7.0.100.preview7 o posterior y NuGet 6.4 o posterior.

Se usa una referencia de paquete global para especificar que todos los proyectos de un repositorio usarán un paquete. Esto incluye paquetes que realizan el control de versiones, amplían la compilación o cualquier otro paquete que necesiten todos los proyectos. Las referencias de paquete global se agregan al grupo de elementos PackageReference con los metadatos siguientes:

  • IncludeAssets="Runtime;Build;Native;contentFiles;Analyzers"
    Esto garantiza que el paquete solo se usa como dependencia de desarrollo y evita cualquier referencia de ensamblado en tiempo de compilación.
  • PrivateAssets="All"
    Esto impide que las referencias globales del paquete sean recogidas por dependencias posteriores.

Los elementos GlobalPackageReference deben colocarse en la Directory.Packages.props para que sean utilizados por todos los proyectos de un repositorio.

<Project>
  <ItemGroup>
    <GlobalPackageReference Include="Nerdbank.GitVersioning" Version="3.5.109" />
  </ItemGroup>
</Project>

Advertencia al usar varios orígenes de paquetes

Al usar la administración central de paquetes, verá una advertencia de NU1507 si tiene más de un origen de paquete definido en la configuración. Para resolver esta advertencia, mapea las fuentes de tu paquete con la asignación de origen del paquete o especifica una única fuente de paquete.

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.

Nota

La administración central de paquetes está en desarrollo activo. Le agradecemos probarlo y proporcionar cualquier comentario que pueda tener en NuGet/Home.