Compartilhar via


PackageReference em arquivos de projeto

As referências de pacote, usando itens <PackageReference> do MSBuild, especificam as dependências de pacotes do NuGet diretamente nos arquivos de projeto, em vez de ter um arquivo packages.config separado. O uso de PackageReference, não afeta outros aspectos do NuGet; por exemplo, as configurações nos arquivos NuGet.Config (incluindo as origens do pacote) ainda são aplicadas, conforme explicado em Configurações comuns do NuGet.

Com o PackageReference, você também pode usar condições do MSBuild para escolher as referências de pacote por estrutura de destino ou por outros agrupamentos. Ele também proporciona um controle refinado sobre as dependências e o fluxo de conteúdo. (Para obter mais informações, consulte o pacote NuGet e a restauração como destinos do MSBuild.)

Suporte do tipo de projeto

Por padrão, PackageReference é usado para projetos .NET, projetos .NET Standard e projetos UWP direcionados ao Windows 10 Build 15063 (Atualização de Criadores) e posteriores, com exceção de projetos UWP do C++. Os projetos do .NET Framework são compatíveis com o PackageReference, mas, no momento, o padrão é packages.config. Para usar PackageReference em um projeto do .NET Framework, migre as dependências do arquivo de packages.config projeto e remova packages.config.

ASP.NET aplicativos destinados ao .NET Framework completo incluem apenas suporte limitado para PackageReference. Não há suporte para tipos de projeto C++ e JavaScript.

Adicionando uma referência de pacote

Adicione uma dependência ao arquivo de projeto usando a seguinte sintaxe:

<ItemGroup>
    <!-- ... -->
    <PackageReference Include="Contoso.Utility.UsefulStuff" Version="3.6.0" />
    <!-- ... -->
</ItemGroup>

Controlar a versão de dependência

A convenção para especificar a versão de um pacote é a mesma que usar packages.config:

<ItemGroup>
    <!-- ... -->
    <PackageReference Include="Contoso.Utility.UsefulStuff" Version="3.6.0" />
    <!-- ... -->
</ItemGroup>

No exemplo acima, 3.6.0 significa qualquer versão que seja >=3.6.0 com preferência pela versão mais baixa, conforme descrito no controle de versão do Pacote.

Usando PackageReference para um projeto sem dependências de pacotes

Avançado: se você não tem pacotes instalados em um projeto (não tem PackageReferences no arquivo de projeto nem um arquivo packages.config), mas deseja que o projeto seja restaurado como o estilo PackageReference, você pode definir uma propriedade de projeto RestoreProjectStyle como PackageReference em seu arquivo de projeto.

<PropertyGroup>
    <!--- ... -->
    <RestoreProjectStyle>PackageReference</RestoreProjectStyle>
    <!--- ... -->
</PropertyGroup>    

Isso pode ser útil se você fizer referência a projetos com estilo PackageReference (projetos existentes no estilo csproj ou SDK). Isso permitirá que os pacotes aos quais esses projetos fazem referência sejam referenciados "transitivamente" pelo seu projeto.

PackageReference e origens

Em projetos PackageReference, as versões de dependência transitiva são resolvidas no momento da restauração. Assim, em projetos PackageReference, todas as fontes precisam estar disponíveis para todas as restaurações.

Versões Flutuantes

Versões flutuante são compatíveis com PackageReference:

<ItemGroup>
    <!-- ... -->
    <PackageReference Include="Contoso.Utility.UsefulStuff" Version="3.6.*" />
    <PackageReference Include="Contoso.Utility.UsefulStuff" Version="3.6.0-beta.*" />
    <!-- ... -->
</ItemGroup>

Controlar ativos de dependência

Você pode estar usando uma dependência puramente como uma ferramenta de desenvolvimento e talvez não queira expor isso aos projetos que consumirão seu pacote. Nesse cenário, você pode usar os metadados do PrivateAssets para controlar esse comportamento.

<ItemGroup>
    <!-- ... -->

    <PackageReference Include="Contoso.Utility.UsefulStuff" Version="3.6.0">
        <PrivateAssets>all</PrivateAssets>
    </PackageReference>

    <!-- ... -->
</ItemGroup>

As seguintes marcas de metadados controlam ativos de dependência:

Tag Description Valor Padrão
IncludeAssets Esses ativos serão consumidos all
ExcludeAssets Esses ativos não serão consumidos none
PrivateAssets Esses ativos serão consumidos, mas não fluem para o projeto pai contentfiles;analyzers;build

Os valores permitidos para essas marcas são os seguintes, com vários valores separados por um ponto-e-vírgula, exceto por all e none, que devem aparecer por si só:

Value Description
compilar Conteúdo da pasta lib e controles se seu projeto puder compilar em relação aos assemblies dentro da pasta
runtime Conteúdo das pastas lib e runtimes e controla se esses assemblies devem ser copiados para o diretório de saída da compilação.
contentFiles Conteúdo da pasta contentfiles
build .props e .targets na pasta build
buildMultitargeting (4.0).props e .targets na pasta buildMultitargeting, para direcionamento entre frameworks diferentes
buildTransitive (5.0+).props e .targets na pasta buildTransitive, para ativos que fluem transitivamente para qualquer projeto de consumo. Veja a página de recurso.
analyzers Analisadores do .NET
nativo Conteúdo da pasta native
none Nenhuma das opções acima é usada.
all Todas as anteriores (exceto none)
<ItemGroup>
    <!-- ... -->
    <!-- Everything except the content files will be consumed by the project -->
    <!-- Everything except content files and analyzers will flow to the parent project-->
    <PackageReference Include="Contoso.Utility.UsefulStuff" Version="3.6.0">
        <IncludeAssets>all</IncludeAssets> <!-- Default is `all`, can be omitted-->
        <ExcludeAssets>contentFiles</ExcludeAssets>
        <PrivateAssets>contentFiles;analyzers</PrivateAssets>
    </PackageReference>
    <!-- ... -->
    <!-- Everything except the compile will be consumed by the project -->
    <!-- Everything except contentFiles will flow to the parent project-->
    <PackageReference Include="Contoso.Utility.SomeOtherUsefulStuff" Version="3.6.0">
        <ExcludeAssets>compile</ExcludeAssets>
        <PrivateAssets>contentFiles</PrivateAssets>
    </PackageReference>
    <!-- ... -->
</ItemGroup>

Observe que, como build não está incluído com PrivateAssets, alvos e propriedades fluirão para o projeto pai. Considere, por exemplo, que a referência acima é usada em um projeto que compila um pacote do NuGet chamado AppLogger. O AppLogger pode consumir os alvos e propriedades de Contoso.Utility.UsefulStuff, assim como os projetos que consomem o AppLogger.

Note

Quando developmentDependency é definido como true em um arquivo .nuspec, isso marca um pacote como uma dependência apenas de desenvolvimento, o que impede que o pacote seja incluído como dependência em outros pacotes. Com PackageReference (NuGet 4.8+), esse sinalizador também significa que ele excluirá os recursos em tempo de compilação. Para obter mais informações, confira Suporte do DevelopmentDependency para PackageReference.

Adicionar uma condição de PackageReference

Você pode usar uma condição para controlar se um pacote está incluído. As condições podem usar qualquer variável MSBuild ou uma variável definida no arquivo de destinos ou props. No entanto, no momento, há suporte apenas para a TargetFramework variável.

Por exemplo, digamos que você esteja direcionando netstandard1.4 também, net452 mas tenha uma dependência aplicável apenas para net452. Nesse caso, você não deseja que um netstandard1.4 projeto que consuma seu pacote adicione essa dependência desnecessária. Para evitar isso, você deve especificar uma condição no PackageReference da seguinte maneira:

<ItemGroup>
    <!-- ... -->
    <PackageReference Include="Newtonsoft.Json" Version="9.0.1" Condition="'$(TargetFramework)' == 'net452'" />
    <!-- ... -->
</ItemGroup>

Um pacote compilado usando este projeto mostrará que Newtonsoft.Json está incluído como uma dependência somente para um destino net452:

O resultado da aplicação de uma condição em PackageReference com o Visual Studio 2017

As condições também podem ser aplicadas no nível de ItemGroup e serão aplicadas a todos os elementos PackageReference filhos:

<ItemGroup Condition = "'$(TargetFramework)' == 'net452'">
    <!-- ... -->
    <PackageReference Include="Newtonsoft.Json" Version="9.0.1" />
    <PackageReference Include="Contoso.Utility.UsefulStuff" Version="3.6.0" />
    <!-- ... -->
</ItemGroup>

GeneratePathProperty

Esse recurso está disponível no NuGet 5.0 ou superior e no Visual Studio 2019 16.0 ou superior.

Às vezes, é desejável fazer referência a arquivos em um pacote de um destino do MSBuild. Em projetos baseados em packages.config, os pacotes são instalados em uma pasta relativa ao arquivo de projeto. No entanto, em PackageReference, os pacotes são consumidos da pasta global-packages, que pode variar de máquina para máquina.

Para preencher essa lacuna, o NuGet introduziu uma propriedade que aponta para o local de onde o pacote será consumido.

Example:

  <ItemGroup>
      <PackageReference Include="Some.Package" Version="1.0.0" GeneratePathProperty="true" />
  </ItemGroup>

  <Target Name="TakeAction" AfterTargets="Build">
    <Exec Command="$(PkgSome_Package)\something.exe" />
  </Target>

Além disso, o NuGet gera automaticamente propriedades para pacotes que contêm uma pasta de ferramentas.

  <ItemGroup>
      <PackageReference Include="Package.With.Tools" Version="1.0.0" />
  </ItemGroup>

  <Target Name="TakeAction" AfterTargets="Build">
    <Exec Command="$(PkgPackage_With_Tools)\tools\tool.exe" />
  </Target>

As propriedades e identidades de pacote do MSBuild não têm as mesmas restrições, portanto, a identidade do pacote precisa ser alterada para um nome amigável do MSBuild, prefixado pela palavra Pkg. Para verificar o nome exato da propriedade gerada, consulte o arquivo nuget.g.props gerado.

Aliases PackageReference

Em alguns casos raros, pacotes diferentes conterão classes no mesmo namespace. A partir do NuGet 5.7 e Visual Studio 2019 Atualização 7, equivalente ao ProjectReference, o PackageReference é compatível com o Aliases. Por padrão, nenhum aliases é fornecido. Quando um alias é especificado, todos os assemblies provenientes do pacote anotado precisam ser referenciados com um alias.

Você pode examinar o uso de exemplo em NuGet\Samples.

No arquivo de projeto, especifique os aliases da seguinte forma:

  <ItemGroup>
    <PackageReference Include="NuGet.Versioning" Version="5.8.0" Aliases="ExampleAlias" />
  </ItemGroup>

E no código, use-o da seguinte maneira:

extern alias ExampleAlias;

namespace PackageReferenceAliasesExample
{
...
        {
            var version = ExampleAlias.NuGet.Versioning.NuGetVersion.Parse("5.0.0");
            Console.WriteLine($"Version : {version}");
        }
...
}

Avisos e erros do NuGet

Esse recurso está disponível no NuGet 4.3 ou superior e no Visual Studio 2017 15.3 ou superior.

Para muitos cenários de empacotamento e restauração, todos os avisos e erros do NuGet são codificados e começam com `NU****`. Todos os avisos e erros do NuGet estão listados na documentação de referência.

O NuGet observa as seguintes propriedades de aviso:

  • TreatWarningsAsErrors, trate todos os avisos como erros.
  • WarningsAsErrors, trate avisos específicos como erros.
  • NoWarn, oculta avisos específicos, para o projeto inteiro ou para todo o pacote.

Examples:

<PropertyGroup>
    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
...
<PropertyGroup>
    <WarningsAsErrors>$(WarningsAsErrors);NU1603;NU1605</WarningsAsErrors>
</PropertyGroup>
...
<PropertyGroup>
    <NoWarn>$(NoWarn);NU5124</NoWarn>
</PropertyGroup>
...
<ItemGroup>
    <PackageReference Include="Contoso.Package" Version="1.0.0" NoWarn="NU1605" />
</ItemGroup>

Suprimindo avisos do NuGet

Embora seja recomendável que você resolva todos os avisos do NuGet durante as operações de empacotar e restaurar, em determinadas situações sua supressão é justificada. Para suprimir um aviso no projeto inteiro, considere fazer:

<PropertyGroup>
    <PackageVersion>5.0.0</PackageVersion>
    <NoWarn>$(NoWarn);NU5104</NoWarn>
</PropertyGroup>
<ItemGroup>
    <PackageReference Include="Contoso.Package" Version="1.0.0-beta.1"/>
</ItemGroup>

Às vezes, os avisos se aplicam apenas a um determinado pacote no gráfico. Você pode optar por suprimir esse aviso de forma mais seletiva adicionando um NoWarn item PackageReference.

<PropertyGroup>
    <PackageVersion>5.0.0</PackageVersion>
</PropertyGroup>
<ItemGroup>
    <PackageReference Include="Contoso.Package" Version="1.0.0-beta.1" NoWarn="NU1603" />
</ItemGroup>

Suprimindo avisos de pacotes NuGet no Visual Studio

No Visual Studio, você também pode suprimir avisos através da IDE.

Bloqueio de dependências

Esse recurso está disponível no NuGet 4.9 ou superior e no Visual Studio 2017 15.9 ou superior.

A entrada da restauração do NuGet é um conjunto de itens PackageReference do arquivo de projeto (dependências de nível superior ou diretas), e a saída é uma resolução completa de todas as dependências do pacote, incluindo as dependências transitivas. Se a lista PackageReference de entrada não tiver sido alterada, o NuGet tenta sempre produzir o mesmo fechamento completo das dependências de pacotes. No entanto, em alguns cenários, isso não poderá ser feito. Por exemplo:

  • Quando você usa versões flutuantes como <PackageReference Include="My.Sample.Lib" Version="4.*"/>. Embora a intenção aqui seja derivar para a versão mais recente sempre que uma restauração de pacotes ocorrer, há cenários em que os usuários exigem que o grafo seja bloqueado em uma determinada versão mais recente e derive para uma versão posterior, se disponível, mediante um gesto explícito.

  • Uma versão mais recente do pacote que corresponde aos requisitos de versão do PackageReference é publicada. Por exemplo:

    • Dia 1: se você especificou <PackageReference Include="My.Sample.Lib" Version="4.0.0"/> , mas as versões disponíveis nos repositórios NuGet eram 4.1.0, 4.2.0 e 4.3.0. Nesse caso, o NuGet teria resolvido para 4.1.0 (versão mínima mais próxima).

    • Dia 2: a versão 4.0.0 é publicada. O NuGet agora encontrará a correspondência exata e começará a resolver para 4.0.0.

  • Uma determinada versão de pacote é removida do repositório. Embora o nuget.org não permita exclusões de pacotes, nem todos os repositórios de pacotes possuem essa restrição. Isso faz com que o NuGet encontre a melhor correspondência quando não puder resolver a versão excluída.

Habilitando o arquivo de bloqueio

Para persistir o fechamento completo das dependências do pacote, você pode aceitar o recurso de arquivo de bloqueio definindo a propriedade RestorePackagesWithLockFile MSBuild para seu projeto:

<PropertyGroup>
    <!--- ... -->
    <RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
    <!--- ... -->
</PropertyGroup>    

Se essa propriedade estiver definida, a restauração do NuGet gerará um arquivo de bloqueio (packages.lock.json) no diretório raiz do projeto que lista todas as dependências do pacote.

Note

Se um projeto tiver o arquivo packages.lock.json no diretório raiz, o arquivo de bloqueio sempre será usado com a restauração, mesmo que a propriedade RestorePackagesWithLockFile não esteja definida. Portanto, outra maneira de optar por esse recurso é através da criação de um arquivo fictício em branco packages.lock.json no diretório raiz do projeto.

restore comportamento com o arquivo de bloqueio

Se um arquivo de bloqueio estiver presente para um projeto, o NuGet usará esse arquivo de bloqueio para execução restore. O NuGet faz uma verificação rápida para ver se houve alguma alteração nas dependências do pacote, conforme mencionado no arquivo de projeto (ou nos arquivos de projetos dependentes), e se não houve alterações, ele apenas restaura os pacotes mencionados no arquivo de bloqueio. Não há reavaliações das dependências do pacote.

Se o NuGet detectar uma alteração nas dependências definidas, conforme mencionado nos arquivos de projeto, ele reavaliará o grafo do pacote e atualizará o arquivo de bloqueio para refletir o novo fechamento do pacote para o projeto.

Para CI/CD e outros cenários, onde você não gostaria de alterar as dependências de pacote de forma imediata, você pode fazer isso configurando o lockedmode para true:

Para o dotnet.exe, execute:

> dotnet.exe restore --locked-mode

Para msbuild.exe, execute:

> msbuild.exe -t:restore -p:RestoreLockedMode=true

Você também pode definir essa propriedade condicional do MSBuild em seu arquivo de projeto:

<PropertyGroup>
    <!--- ... -->
    <RestoreLockedMode>true</RestoreLockedMode>
    <!--- ... -->
</PropertyGroup> 

Se o modo de bloqueio for true, a restauração restaurará os pacotes exatos conforme listados no arquivo de bloqueio ou falhará se você tiver atualizado as dependências de pacote definidas para o projeto após a criação do arquivo de bloqueio.

Bloquear arquivos e PrunePackageReference

PrunePackageReference altera as dependências de um projeto removendo pacotes transitivos desnecessários. Embora a remoção desses pacotes não tenha impacto no runtime, isso afetará os arquivos de bloqueio. Se você habilitar a poda para um projeto existente, sempre que o arquivo de bloqueio for regenerado, isso pode resultar em menos pacotes do que antes da poda. O arquivo de bloqueio atualizado verifica se o modo bloqueado de poderes está sendo podado, o que significa que, se você habilitou a poda em um projeto, a verificação contabilizará os pacotes que são podados. No entanto, na próxima vez que o arquivo de bloqueio for regenerado, ele excluirá os pacotes podados, portanto, você poderá ver uma diferença maior do que o normal.

Tornar o arquivo de bloqueio parte de seu repositório de origem

Se você estiver criando um aplicativo, um executável e o projeto em questão estiver no início da cadeia de dependências, faça check-in do arquivo de bloqueio no repositório de código-fonte para que o NuGet possa usá-lo durante a restauração.

No entanto, se o projeto for um projeto de biblioteca que você não envia ou um projeto de código comum do qual outros projetos dependem, você não deverá fazer check-in do arquivo de bloqueio como parte do código-fonte. Não há nenhum dano em manter o arquivo de bloqueio, mas as dependências do pacote bloqueado para o projeto de código comum não podem ser usadas, conforme listado no arquivo de bloqueio, durante a restauração/compilação de um projeto que depende desse projeto de código comum.

Example:

ProjectA
  |------> PackageX 2.0.0
  |------> ProjectB
             |------>PackageX 1.0.0

Se ProjectA tiver uma dependência na versão PackageX de 2.0.0 e também referenciar ProjectB que depende da versão PackageX, então o arquivo de bloqueio de 1.0.0 listará uma dependência na versão ProjectB de PackageX. No entanto, quando ProjectA for criado, seu arquivo de bloqueio conterá uma dependência na versão PackageX e 2.0.0, conforme listado no arquivo de bloqueio de 1.0.0. Portanto, o arquivo de bloqueio de um projeto de código comum tem pouco a dizer sobre os pacotes resolvidos de projetos que dependem dele.

Extensibilidade do arquivo de bloqueio

Você pode controlar vários comportamentos de restauração com o arquivo de bloqueio conforme descrito abaixo:

NuGet.exe opção Opção dotnet Opção equivalente do MSBuild Description
-UseLockFile --use-lock-file RestorePackagesWithLockFile Opta pelo uso de um arquivo de bloqueio.
-LockedMode --locked-mode RestoreLockedMode Habilita o modo de bloqueio para a restauração. Isso é útil em cenários de CI/CD em que você deseja builds repetidos.
-ForceEvaluate --force-evaluate RestoreForceEvaluate Esta opção é útil com pacotes que têm a versão flutuante definida no projeto. Por padrão, a restauração do NuGet não atualizará automaticamente a versão do pacote em cada restauração, a menos que você execute a restauração com esta opção.
-LockFilePath --lock-file-path NuGetLockFilePath Define o local de um arquivo de bloqueio personalizado para um projeto. Por padrão, o NuGet é compatível com packages.lock.json no diretório raiz. Se você tiver vários projetos no mesmo diretório, o NuGet oferecerá suporte ao arquivo de bloqueio packages.<project_name>.lock.json específico do projeto

Resolvedor de Dependência do NuGet

O resolvedor de dependência do NuGet segue as quatro regras, conforme descrito no documento de resolução de dependência.

Para melhorar o desempenho e a escalabilidade da operação de restauração, o algoritmo de restauração foi reescrito na versão 6.12. A partir da versão 6.12, o novo algoritmo de restauração é habilitado por padrão para todos os projetos PackageReference. Embora o novo algoritmo de restauração seja funcionalmente equivalente ao anterior, como acontece com qualquer software, bugs são possíveis. Para reverter para a implementação anterior, defina a propriedade MSBuild RestoreUseLegacyDependencyResolver como true.

Caso você enfrente falhas de restauração na versão 6.12, .NET 9 ou 17.12 que não estavam sendo reproduzidas em versões anteriores, registre um problema no GitHub. Quaisquer diferenças entre os algoritmos antigos e novos podem ter impactos diferentes, como durante a compilação ou no runtime. Também há a chance de que as alterações não levem a falhas, mas a diferentes versões de pacotes sendo restauradas. Se você acha que pode ser afetado por qualquer alteração, aqui estão as etapas que você pode executar para verificar se as alterações no algoritmo de restauração do NuGet são a causa raiz.

O Restore grava seus resultados no diretório MSBuildProjectExtensionsPath, que pode ser comparado com os algoritmos novos e antigos para achar diferenças. Normalmente, esta é a pasta obj da sua construção. Você pode usar msbuild.exe ou dotnet.exe para as próximas etapas.

  1. Remova a pasta obj do seu projeto.

  2. Execute msbuild -t:restore

  3. Salve o conteúdo de obj em uma localização indicando que é o comportamento new.

  4. Execute msbuild -t:restore -p:RestoreUseLegacyDependencyResolver="true".

  5. Salve o conteúdo de obj em uma localização indicando que é o comportamento legacy.

  6. Compare os arquivos nos dois diretórios, particularmente project.assets.json.

    Ferramentas que podem realçar diferenças são especialmente úteis para isso (por exemplo, no Visual Studio Code, abra ambos os arquivos e use o clique com o botão direito do mouse em "selecionar para comparar" e "comparar com selecionado").

Se você seguir o método acima, deve haver exatamente 1 diferença entre os arquivos project.assets.json:

      "projectStyle": "PackageReference",
+     "restoreUseLegacyDependencyResolver": true,
      "fallbackFolders": [

Se houver mais diferenças, registre um problema no GitHub com todos os detalhes.

AssetTargetFallback

A propriedade AssetTargetFallback permite especificar versões adicionais de estrutura compatíveis para projetos que ele referencia e pacotes NuGet que consome.

Se você especificar uma dependência de pacote usando PackageReference, mas esse pacote não contiver recursos compatíveis com a estrutura de destino dos seus projetos, a propriedade AssetTargetFallback será utilizada. A compatibilidade do pacote referenciado é reverificada usando cada framework de destino especificado em AssetTargetFallback. Quando um project ou um package for referenciado através de AssetTargetFallback, o aviso NU1701 será gerado.

Consulte a tabela abaixo para ver exemplos de como AssetTargetFallback afeta a compatibilidade.

Estrutura do projeto AssetTargetFallback Estruturas de pacote Result
.NET Framework 4.7.2 .NET Standard 2.0 .NET Standard 2.0
Aplicativo .NET Core 3.1 .NET Standard 2.0, .NET Framework 4.7.2 .NET Standard 2.0
Aplicativo .NET Core 3.1 .NET Framework 4.7.2 Incompatível, falha com NU1202
Aplicativo .NET Core 3.1 net472;net471 .NET Framework 4.7.2 .NET Framework 4.7.2 com NU1701

É possível especificar vários frameworks usando ; como delimitador. Para adicionar uma estrutura de fallback, você pode fazer o seguinte:

<AssetTargetFallback Condition=" '$(TargetFramework)'=='netcoreapp3.1' ">
    $(AssetTargetFallback);net472;net471
</AssetTargetFallback>

Você pode deixar $(AssetTargetFallback) de fora se desejar substituir, em vez de adicionar aos valores de AssetTargetFallback existentes.

Note

Se você estiver usando um projeto baseado em .NET SDK, os valores $(AssetTargetFallback) apropriados serão configurados e você não precisará defini-los manualmente.

$(PackageTargetFallback) era um recurso anterior que tentava resolver esse desafio, mas está estruturalmente quebrado e não deve ser usado. Para migrar de $(PackageTargetFallback) para $(AssetTargetFallback), basta alterar o nome da propriedade.

PrunePackageReference

O Runtime do .NET está em constante evolução, com melhorias de desempenho e novas APIs a cada versão. Novos recursos adicionados ao .NET também às vezes são fornecidos como pacotes, para que os desenvolvedores que usam estruturas de destino mais antigas possam usar a biblioteca, como System.Text.Json. Isso geralmente pode levar a um System.Text.Json 8.0.0 em um projeto direcionado a .NET 9 ou .NET 8. Esta dependência não é necessária e a resolução de conflitos de build não usaria o assembly proveniente do pacote, pois ele já está disponível no runtime do .NET. A partir do NuGet versão 6.13 e do SDK do .NET 9.0.200, PrunePackageReference permite a remoção desses pacotes no momento da restauração para projetos baseados no SDK do .NET. A primeira iteração de poda afetou apenas pacotes transitivos, mas a partir do .NET SDK 10, a poda de pacotes também afeta os pacotes diretos.

A poda de pacote está disponível como um recurso de aceitação com o SDK do .NET 9 e está habilitada por padrão para todas as estruturas de um projeto direcionado >= .NET 10.0 ao SDK do .NET 10.

"A poda de pacotes só está disponível com o resolvedor de dependências padrão, conforme lançado na versão 6.12."

Especificação prunePackageReference

A lista de pacotes a serem podados é definida com o item PrunePackageReference.

Attributes Description
Version Especifica a versão máxima a ser podada. 1.0.0 significa que todos os pacotes até e incluindo 1.0.0 serão removidos. Para 1.0.0, 0.9.0 e 1.0.0 serão podados, mas 1.0.1 não será.

As propriedades a seguir podem ser usadas para modificar o comportamento de poda.

PropertyName Description
RestoreEnablePackagePruning Habilita a poda de pacote para os pacotes especificados com PrunePackageReference. Essa propriedade é por estrutura de destino e os valores válidos são true e false. Os padrões podem ser diferentes com base no SDK do .NET, conforme definido acima.

O SDK do .NET predefini a lista de pacotes a serem removidos para você.

Como funciona PrunePackageReference

Quando um pacote é especificado para ser podado durante a restauração, ele é removido do grafo de dependência. Quando um pacote é podado, há uma mensagem, visível em verbosidade detalhada, indicando que o pacote foi removido para a estrutura de destino fornecida.

Para pacotes transitivos, ou seja, dependências de outros pacotes ou projetos, os pacotes não são baixados e não aparecem em nenhuma das saídas do NuGet.

Para pacotes diretos, PrivateAssets='all' e IncludeAssets='none' são aplicados implicitamente.

  • IncludeAssets='none' garante que os assemblies desse pacote não sejam usados durante o build. Antes de a eliminação existir, a resolução de conflitos durante a compilação garantiu que os assemblies de plataforma tivessem preferência sobre aqueles provenientes dos pacotes.
  • PrivateAssets='all' garante que os pacotes não sejam incluídos em outros pacotes ou por meio de referências de projeto.

Example:

Um projeto como o seguinte:

  <PropertyGroup>
    <TargetFrameworks>net9.0;netstandard2.0</TargetFrameworks>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="System.Text.Json" Version="9.0.4" />
  </ItemGroup>

terá um nuspec com as seguintes dependências:

<dependencies>
    <group targetFramework=".NETFramework4.7.2">
        <dependency id="System.Text.Json" version="9.0.4" />
    </group>
    <group targetFramework="net9.0">
    </group>
</dependencies>

Quando um PackageReference direto pode ser completamente removido do seu projeto e uma das estruturas de projeto é .NET 10 ou mais recente, NU1510 será gerado solicitando que você remova o pacote. Seguir essa sugestão reduzirá a complexidade do grafo do projeto.

A tabela a seguir resume todos os comportamentos de pruning de pacote.

Disposição de dependência Behavior
Corresponde à ID de um pacote transitivo que vem por meio de outro pacote Prune
Corresponde à ID de um pacote transitivo que vem por meio de outro projeto Prune
Corresponde ao ID do PackageReference direto Aplique PrivateAssets='all' e IncludeAssets='none' e aumente o aviso NU1510 quando o pacote puder ser removido de todas as estruturas de trabalho e o projeto estiver destinado ao .NET 10.
Corresponde à ID de um ProjectReference Não remova e não gere o aviso NU1511 quando o projeto destina-se ao .NET 10

Aplicativos PrunePackageReference

Os benefícios da poda de pacote são duplos:

  • Benefícios de desempenho, em virtude da redução do número de pacotes em um grafo de dependência
  • Redução de falsos positivos por scanners de componentes, como NuGetAudit

A poda é particularmente valiosa ao auditar pacotes com NuGetAuditMode definido como all. Se você estiver usando o .NET 9, recomendamos que você experimente a poda definindo RestoreEnablePackagePruningtruecomo .