Compartilhar via


Suporte a várias versões do .NET

Muitas bibliotecas têm como destino uma versão específica do .NET Framework. Por exemplo, você pode ter uma versão da biblioteca específica da UWP e outra que aproveita os recursos no .NET Framework 4.6. Para acomodar isso, o NuGet dá suporte à colocação de várias versões da mesma biblioteca em um único pacote.

Este artigo descreve o layout de um pacote NuGet, independentemente de como o pacote ou assemblies são criados (ou seja, o layout é o mesmo, seja usando vários arquivos .csproj de estilo não SDK e um arquivo .nuspec personalizado ou um único arquivo .csproj de estilo SDK para múltiplos destinos). Para um projeto no estilo SDK, os destinos do pacote NuGet sabem como o pacote deve ser colocado e automatiza a colocação dos assemblies nas pastas lib corretas e a criação de grupos de dependência para cada estrutura de destino (TFM). Para obter instruções detalhadas, consulte Suporte a várias versões do .NET Framework em seu arquivo de projeto.

Você deve definir manualmente o pacote conforme descrito neste artigo ao usar o método de diretório de trabalho baseado em convenção descrito na criação de um pacote. Para um projeto no estilo SDK, o método automatizado é recomendado, mas você também pode optar por definir manualmente o pacote, conforme descrito neste artigo.

Estrutura de pastas da versão do framework

Ao criar um pacote que contém apenas uma versão de uma biblioteca ou é direcionado a vários frameworks, você deve sempre fazer subpastas em lib usando diferentes nomes de frameworks que diferenciam maiúsculas de minúsculas com a seguinte convenção:

lib\{framework name}[{version}]

Para obter uma lista completa de nomes com suporte, consulte a referência de Estruturas de Destino.

Você nunca deve ter uma versão da biblioteca que não seja específica a uma estrutura e colocada diretamente na pasta raiz lib . (Essa funcionalidade só tinha suporte com packages.config). Isso tornaria a biblioteca compatível com qualquer estrutura de destino e permitiria que ela fosse instalada em qualquer lugar, provavelmente resultando em erros inesperados de runtime. A adição de assemblies na pasta raiz (como lib\abc.dll) ou subpastas (como lib\abc\abc.dll) foi preterida e ignorada ao usar o formato PackagesReference.

Por exemplo, a seguinte estrutura de pastas oferece suporte a quatro versões de um assembly que são específicas para diferentes frameworks.

\lib
    \net46
        \MyAssembly.dll
    \net461
        \MyAssembly.dll
    \uap
        \MyAssembly.dll
    \netcore
        \MyAssembly.dll

Para incluir facilmente todos esses arquivos ao compilar o pacote, use um curinga recursivo ** na <files> seção de seu .nuspec:

<files>
    <file src="lib\**" target="lib/{framework name}[{version}]" />
</files>

Pastas específicas da arquitetura de sistema

Se você tiver assemblies específicos da arquitetura, ou seja, assemblies separados destinados a ARM, x86 e x64, você deverá colocá-los em uma pasta chamada runtimes dentro de subpastas chamadas {platform}-{architecture}\lib\{framework} ou {platform}-{architecture}\native. Por exemplo, a seguinte estrutura de pastas acomodaria DLLs nativas e gerenciadas direcionadas ao Windows 10 e à uap10.0 estrutura:

\runtimes
    \win10-arm
        \native
        \lib\uap10.0
    \win10-x86
        \native
        \lib\uap10.0
    \win10-x64
        \native
        \lib\uap10.0

Esses assemblies só estarão disponíveis em tempo de execução, portanto, se você quiser fornecer também o assembly correspondente de tempo de compilação, coloque o arquivo de assembly na pasta /ref/{tfm}.

Note que o NuGet sempre escolhe esses ativos de compilação ou de execução de uma pasta, portanto, se houver alguns ativos compatíveis a partir de /ref, então /lib será ignorado ao adicionar assemblies em tempo de compilação. Da mesma forma, se houver alguns recursos compatíveis de /runtimes, então /lib também serão ignorados para runtime.

Consulte Criar Pacotes UWP para obter um exemplo de referência a esses arquivos no .nuspec manifesto.

Além disso, consulte Empacotando um componente de aplicativo da Windows Store com o NuGet

Correspondência de versões de assembly e da estrutura de destino em um projeto

Quando o NuGet instala um pacote que tem várias versões de assembly, ele tenta corresponder o nome da estrutura do assembly com a estrutura de destino do projeto.

Se uma correspondência não for encontrada, o NuGet copiará o assembly para a versão mais alta que seja menor ou igual ao framework de destino do projeto, se disponível. Se nenhum assembly compatível for encontrado, o NuGet retornará uma mensagem de erro apropriada.

Por exemplo, considere a seguinte estrutura de pastas em um pacote:

\lib
    \net45
        \MyAssembly.dll
    \net461
        \MyAssembly.dll

Ao instalar esse pacote em um projeto direcionado ao .NET Framework 4.6, o NuGet instala o assembly na net45 pasta, pois essa é a versão mais alta disponível que é menor ou igual a 4.6.

Se o projeto for direcionado ao .NET Framework 4.6.1, por outro lado, o NuGet instalará o assembly na net461 pasta.

Se o projeto for direcionado ao .NET Framework 4.0 e anterior, o NuGet lançará uma mensagem de erro apropriada para não localizar o assembly compatível.

Agrupando assemblies por versão da estrutura

O NuGet copia assemblies de apenas uma única pasta de biblioteca no pacote. Por exemplo, suponha que um pacote tenha a seguinte estrutura de pastas:

\lib
    \net40
        \MyAssembly.dll (v1.0)
        \MyAssembly.Core.dll (v1.0)
    \net45
        \MyAssembly.dll (v2.0)

Quando o pacote é instalado em um projeto direcionado ao .NET Framework 4.5, MyAssembly.dll (v2.0) é o único assembly instalado. MyAssembly.Core.dll (v1.0) não está instalado porque não está listado na net45 pasta. O NuGet se comporta dessa maneira porque MyAssembly.Core.dll pode ter sido mesclado à versão 2.0 de MyAssembly.dll.

Se você quiser MyAssembly.Core.dll ser instalado para o .NET Framework 4.5, coloque uma cópia na net45 pasta.

Agrupando assemblies por perfil de estrutura

O NuGet também dá suporte ao direcionamento de um perfil de estrutura específico acrescentando um traço e o nome do perfil ao final da pasta.

lib{framework name}-{profile}

Os perfis com suporte são os seguintes:

  • client: Perfil do Cliente
  • full: Perfil Completo
  • wp:Windows Phone
  • cf: Compact Framework

Declarando dependências (Avançado)

Ao empacotar um arquivo de projeto, o NuGet tenta gerar automaticamente as dependências do projeto. As informações nesta seção sobre como usar um arquivo .nuspec para declarar dependências normalmente são necessárias apenas para cenários avançados.

(Versão 2.0+) Você pode declarar dependências de pacote no .nuspec correspondente à estrutura de destino do projeto de destino usando <group> elementos dentro do <dependencies> elemento. Para obter mais informações, consulte o elemento de dependências.

Cada grupo tem um atributo nomeado targetFramework e contém zero ou mais <dependency> elementos. Essas dependências são instaladas em conjunto quando a estrutura de destino é compatível com o perfil da estrutura do projeto. Consulte as estruturas de destino para obter os identificadores exatos da estrutura.

É recomendável usar um grupo por TFM (Target Framework Moniker) para arquivos nas pastas lib/ e ref/ .

O exemplo a seguir mostra diferentes variações do <group> elemento:

<dependencies>

    <group targetFramework="net472">
        <dependency id="jQuery" version="1.10.2" />
        <dependency id="WebActivatorEx" version="2.2.0" />
    </group>

    <group targetFramework="net20">
    </group>

</dependencies>

Determinando qual alvo do NuGet usar

Ao empacotar bibliotecas voltadas à Biblioteca de Classes Portátil, pode ser complicado determinar qual destino do NuGet você deve usar em seus nomes de pasta e no arquivo .nuspec, especialmente ao mirar apenas em um subconjunto da PCL. Os seguintes recursos externos ajudarão você com isso:

Arquivos de conteúdo e scripts do PowerShell

Aviso

Arquivos de conteúdo mutáveis e execução de script estão disponíveis apenas com o packages.config formato; eles são preteridos com todos os outros formatos e não devem ser usados para novos pacotes.

Com packages.config, arquivos de conteúdo e scripts do PowerShell podem ser agrupados por estrutura de destino usando a mesma convenção de pasta dentro das pastas content e tools. Por exemplo:

\content
    \net46
        \MyContent.txt
    \net461
        \MyContent461.txt
    \uap
        \MyUWPContent.html
    \netcore
\tools
    init.ps1
    \net46
        install.ps1
        uninstall.ps1
    \uap
        install.ps1
        uninstall.ps1

Se uma pasta de estrutura for deixada vazia, o NuGet não adicionará referências de assembly ou arquivos de conteúdo ou executará os scripts do PowerShell para essa estrutura.

Observação

Como init.ps1 é executado no nível da solução e não depende do projeto, ele deve ser colocado diretamente na tools pasta. Será ignorado se colocado em uma pasta de framework.