Migrar de packages.config para PackageReference

O Visual Studio 2017 versão 15.7 e posterior oferece suporte à migração de um projeto do formato de gerenciamento packages.config para o formato PackageReference.

Benefícios do uso de PackageReference

  • Gerencie todas as dependências do projeto em um só lugar: assim como as referências de projeto para projeto e referências de assembly, as referências de pacotes NuGet (usando o nó PackageReference) são gerenciadas diretamente dentro dos arquivos do projeto, em vez de usar um arquivo packages.config separado.
  • Exibição limpa das dependências de alto nível: ao contrário do packages.config, o PackageReference lista apenas os pacotes NuGet que você instalou diretamente no projeto. Como resultado, a interface do usuário do Gerenciador de Pacotes do NuGet e o arquivo de projeto não ficam cheios de dependências de baixo nível.
  • Melhoras no desempenho: ao usar o PackageReference, os pacotes são mantidos na pasta global-packages (conforme descrito em Gerenciar pacotes globais e pastas de cache, em vez de em uma pasta packages na solução. Como resultado, PackageReference é executado mais rapidamente e consome menos espaço em disco.
  • Controle rigoroso das dependências e do fluxo de conteúdo: o uso dos recursos existentes do MSBuild permite fazer referência condicional a um pacote NuGet e escolher as referências do pacote por estrutura de destino, configuração, plataforma ou outros elementos.

Limitações

  • O NuGet PackageReference não está disponível no Visual Studio 2015 e versões anteriores. Os projetos migrados podem ser abertos apenas no Visual Studio 2017 e posterior.
  • Atualmente, a migração não está disponível para projetos C++ e ASP.NET.
  • Alguns pacotes podem não ser totalmente compatíveis com o PackageReference. Para obter mais informações, confira Problemas de compatibilidade de pacotes.

Além disso, há algumas diferenças em como o PackageReferences funciona, comparado ao packages.config. Por exemplo, as Restrições em versões de atualização não são compatíveis no PackageReference, porém esse formato adiciona suporte para as Versões flutuantes.

Problemas conhecidos

  1. A opção Migrate packages.config to PackageReference... não está disponível no menu de contexto de clique com o botão direito do mouse

Problema

Quando um projeto é aberto pela primeira vez, o NuGet pode não ser inicializado até que uma operação do NuGet seja executada. Isso faz com que a opção de migração não apareça no menu de contexto com o botão direito do mouse em packages.config ou References.

Solução alternativa

Execute qualquer uma das seguintes ações NuGet:

  • Abra a interface do usuário do Gerenciador de Pacotes, clique com o botão direito do mouse em References e selecione Manage NuGet Packages...
  • Abra o Console do Gerenciador de Pacotes em Tools > NuGet Package Manager, selecione Package Manager Console
  • Execute a restauração do NuGet, clique com o botão direito do mouse no nó de solução no Gerenciador de Soluções e selecione Restore NuGet Packages
  • Compile o projeto, o que também acionará a restauração do NuGet

Agora você deve conseguir ver a opção de migração. Observe que essa opção não tem suporte e não será exibida para os tipos de projeto do ASP.NET e C++.

Etapas da migração

Observação

Antes do início da migração, o Visual Studio cria um backup do projeto para permitir que você reverta para packages.config, se necessário.

  1. Abra uma solução que contém um projeto que usa packages.config.

  2. No Gerenciador de Soluções, clique com o botão direito do mouse no nó Referências ou no arquivo packages.config e selecione Migrar packages.config para PackageReference....

  3. O migrador analisa as referências do pacote NuGet do projeto e tenta categorizá-las em Dependências de nível superior (pacotes NuGet instalados diretamente) e Dependências transitivas (pacotes instalados como dependências de pacotes de nível superior).

    Observação

    O PackageReference oferece suporte à restauração transitiva de pacotes e resolve dependências de modo dinâmico, o que significa que as dependências transitivas não precisam ser instaladas explicitamente.

  4. (Opcional) Você pode tratar um pacote NuGet classificado como dependência transitiva como uma dependência de nível superior, selecionando a opçãoNível Superior para o pacote. Essa opção é configurada automaticamente para pacotes contendo ativos que não fluem transitivamente (nas pastas build, buildCrossTargeting, contentFiles ou analyzers) e aqueles marcados como uma dependência de desenvolvimento (developmentDependency = "true").

  5. Analise quaisquer problemas de compatibilidade de pacotes.

  6. Selecione OK para iniciar a migração.

  7. No final da migração, o Visual Studio fornece um relatório com um caminho para o backup, a lista de pacotes instalados (dependências de nível superior), uma lista de pacotes referenciados como dependências transitivas e uma lista de problemas de compatibilidade identificados no início da migração. O relatório é salvo na pasta de backup.

  8. Valide se a solução é compilada e executada. Se você encontrar problemas, registre um problema no GitHub.

Como reverter para packages.config

  1. Feche o projeto migrado.

  2. Copie o arquivo do projeto e packages.config do backup (geralmente, <solution_root>\MigrationBackup\<unique_guid>\<project_name>\) para a pasta do projeto. Exclua a pasta obj, se ela existir no diretório raiz do projeto.

  3. Abra o projeto.

  4. Abra o Console do Gerenciador de Pacotes usando o comando de menu Ferramentas > Gerenciador de Pacotes NuGet > Console do Gerenciador de Pacotes.

  5. Execute o seguinte comando no console:

    update-package -reinstall
    

Criar um pacote após a migração

Quando a migração estiver concluída, recomendamos que você adicione uma referência ao pacote nuget nuget.build.tasks.pack e use msbuild -t:pack para criar o pacote. Embora você possa usar dotnet.exe pack em vez de msbuild -t:pack em alguns cenários, isso não é recomendado.

Problemas de compatibilidade de pacotes

Alguns aspectos que tinham suporte em packages.config não têm suporte em PackageReference. O migrador analisa e detecta tais problemas. Qualquer pacote que tenha um ou mais dos problemas a seguir pode não se comportar conforme esperado após a migração.

Os scripts "install.ps1" são ignorados quando o pacote é instalado após a migração

  • Descrição: com o PackageReference, os scripts install.ps1 e uninstall.ps1 do PowerShell não são executados durante a instalação ou desinstalação de um pacote.

  • Impacto potencial: os pacotes que dependem desses scripts para configurar algum comportamento no projeto de destino podem não funcionar conforme o esperado.

Os ativos "conteúdo" não estão disponíveis quando o pacote é instalado após a migração

  • Descrição: os ativos na pasta content de um pacote não são compatíveis com o PackageReference e são ignorados. PackageReference adiciona suporte para contentFiles para ter um melhor suporte transitivo e conteúdo compartilhado.

  • Impacto potencial: os ativos em content não são copiados no projeto e o código do projeto que depende da presença desses recursos exige a refatoração.

Transformações XDT não são aplicadas quando o pacote é instalado após a atualização

  • Descrição: as transformações XDT não são compatíveis com o PackageReference e os arquivos .xdt são ignorados durante a instalação ou desinstalação de um pacote.

  • Impacto potencial: as transformações do XDT não são aplicadas a nenhum arquivo XML do projeto, mais comumente o web.config.install.xdt e web.config.uninstall.xdt, o que significa que o arquivo web.config do projeto não é atualizado quando o pacote é instalado ou desinstalado.

Assemblies na raiz lib são ignorados quando o pacote é instalado após a migração

  • Descrição: com o PackageReference, os assemblies presentes na raiz da pasta lib sem uma subpasta específica da estrutura de destino são ignorados. O NuGet procura por uma subpasta correspondente ao TFM (moniker da estrutura de destino) que corresponde à estrutura de destino do projeto e instala os conjuntos correspondentes no projeto.

  • Impacto potencial: os pacotes que não têm uma subpasta correspondente ao moniker da estrutura de destino (TFM) que corresponde à estrutura de destino do projeto podem não se comportar como esperado após a transição ou apresentar falha de instalação durante a migração.

Encontrou um problema? Relate-o!

Se você tiver algum problema com a experiência de migração, registre um problema no repositório GitHub do NuGet.