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 único proyecto puede ser fácil. La administración de dependencias para soluciones de varios proyectos puede resultar difícil a medida que empiezan a escalarse 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 central de paquetes(CPM) de NuGet para llevar a cabo todas estas tareas desde la comodidad de una única ubicación.

Históricamente, las dependencias de paquetes de NuGet se han administrado en una o dos ubicaciones:

  • packages.config: un archivo XML que se usa en los 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 MSBuild define dependencias del paquete de NuGet.

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

La característica está disponible en todas las herramientas integradas de NuGet a partir de las siguientes versiones.

Las herramientas anteriores omitirán las configuraciones y características de la administración central de paquetes. Para usar esta característica en toda su extensión, 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 MSBuild basados en <PackageReference>, incluido CSPROJ heredado, siempre que se utilicen 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 ManagePackageVersionsCentrally de MSBuild en true.

Dentro, puede definir cada una de las versiones de paquete correspondientes necesarias para los proyectos mediante elementos <PackageVersion /> que definan 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 atributo <PackageReference /> pero se omite Version, ya que la versión se obtendrá a partir de un elemento correspondiente <PackageVersion />.

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

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

Reglas de la administración central de paquetes

El archivo Directory.Packages.props tiene varias reglas en lo que respecta 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 tiene varios archivos Directory.Packages.props en el repositorio, se evaluará el archivo más cercano al directorio del proyecto. Esto le permite tener un control adicional en varios niveles del repositorio.

A continuación se muestra un ejemplo; tenga en cuenta 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 el primero más cercano al proyecto. Si tiene varios Directory.Packages.props, debe importar el primario manualmente mientras la raíz Directory.Packages.props no lo haría.

Introducción

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. Declare elementos <PackageVersion /> en el objeto Directory.Packages.props.
  3. Declare elementos <PackageReference /> sin atributos Version en los archivos del proyecto.

Para obtener una idea del aspecto que puede tener la administración central de paquetes, consulte nuestro repositorio de ejemplo.

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.

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

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

Invalidación de las versiones del paquete

Puede invalidar una versión de paquete individual mediante la propiedad VersionOverride de un elemento <PackageReference />. Esto invalida cualquier <PackageVersion /> definido de forma centralizada.

<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 CentralPackageVersionOverrideEnabled de MSBuild en false en un proyecto o en un archivo de importación Directory.Packages.props o Directory.Build.props:

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

Cuando esta característica está deshabilitada, si se especifica VersionOverride en cualquier elemento <PackageReference />, se 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 hacerlo estableciendo la propiedad ManagePackageVersionsCentrally de MSBuild 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 paquetes globales se agregan al grupo de artículos 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 de paquetes globales se recojan mediante dependencias de nivel inferior.

Todos los proyectos de un repositorio deben colocar los elementos GlobalPackageReference en el Directory.Packages.props que se va a usar:

<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 NU1507 si tiene más de un origen de paquete definido en la configuración. Para resolver esta advertencia, asigne los orígenes de paquete con la asignación de orígenes de paquete o especifique un único origen 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 de paquetes central está en desarrollo activo. Les agradecemos que la prueben y que nos haga llegar sus comentarios a NuGet/Home.