Dela via


Stöd för flera .NET-versioner

Många bibliotek riktar in sig på en specifik version av .NET Framework. Du kan till exempel ha en version av biblioteket som är specifik för UWP och en annan version som drar nytta av funktioner i .NET Framework 4.6. För att hantera detta har NuGet stöd för att placera flera versioner av samma bibliotek i ett enda paket.

Den här artikeln beskriver layouten för ett NuGet-paket, oavsett hur paketet eller sammansättningarna skapas (dvs. layouten är densamma oavsett om du använder flera .csproj-filer i icke-SDK-stil och en anpassad .nuspec-fil eller en enda SDK-stil med flera mål). För ett SDK-projekt vet NuGet-paketmål hur paketet måste läggas ut och automatiserar installationen av sammansättningarna i rätt lib-mappar och skapar beroendegrupper för varje målramverk (TFM). Detaljerade anvisningar finns i Stöd för flera .NET Framework-versioner i projektfilen.

Du måste manuellt lägga ut paketet enligt beskrivningen i den här artikeln när du använder den konventionsbaserade arbetskatalogmetoden som beskrivs i Skapa ett paket. För ett SDK-projekt rekommenderas den automatiserade metoden, men du kan också välja att manuellt lägga ut paketet enligt beskrivningen i den här artikeln.

Mappstruktur för ramverksversion

När du bygger ett paket som innehåller endast en version av ett bibliotek eller riktar sig mot flera ramverk, skapar du alltid undermappar under lib, med olika skiftlägeskänsliga ramverksnamn enligt följande konvention:

lib\{framework name}[{version}]

En fullständig lista över namn som stöds finns i referensen för Målramverk.

Du bör aldrig ha en version av biblioteket som inte är specifik för ett ramverk och som placeras direkt i rotmappen lib . (Den här funktionen stöds endast med packages.config). Detta skulle göra biblioteket kompatibelt med alla målsystem och möjliggöra installation var som helst, vilket sannolikt resulterar i oväntade körfel. Att lägga till sammansättningar i rotmappen (till exempel lib\abc.dll) eller undermappar (till exempel lib\abc\abc.dll) har föråldrats och ignoreras när du använder PackagesReference-formatet.

Följande mappstruktur stöder till exempel fyra versioner av en sammansättning som är ramverksspecifik:

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

För att enkelt inkludera alla dessa filer när du bygger paketet, använd ett rekursivt ** jokertecken i <files>-avsnittet av .nuspec.

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

Arkitekturspecifika mappar

Om du har arkitekturspecifika sammansättningar, d.v.s. separata sammansättningar som är avsedda för ARM, x86 och x64, måste du placera dem i en mapp med namnet runtimes i undermappar med namnet {platform}-{architecture}\lib\{framework} eller {platform}-{architecture}\native. Följande mappstruktur skulle till exempel rymma både interna och hanterade DLL:er för Windows 10 och ramverket uap10.0 :

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

Dessa sammanställningar är endast tillgängliga vid körningstid, så om du även vill tillhandahålla den motsvarande kompileringstidsmonteringen, ha då en AnyCPU montering i /ref/{tfm} mappen.

Observera att NuGet alltid väljer dessa kompilerings- eller körningstillgångar från en mapp, så om det finns några kompatibla tillgångar från /ref/lib ignoreras de för att lägga till kompileringstidssammansättningar. På samma sätt, om det finns några kompatibla tillgångar från /runtimes, då kommer /lib också att ignoreras under körning.

Se Skapa UWP-paket för ett exempel på hur du refererar till dessa filer i manifestet .nuspec .

Mer information finns i Paketering av en Windows Store-appkomponent med NuGet

Matchande sammansättningsversioner och målramverket i ett projekt

När NuGet installerar ett paket som har flera sammansättningsversioner försöker det matcha ramverksnamnet för sammansättningen med projektets målramverk.

Om en matchning inte hittas kopierar NuGet sammansättningen för den högsta versionen som är mindre än eller lika med projektets målramverk, om det är tillgängligt. Om ingen kompatibel sammansättning hittas returnerar NuGet ett lämpligt felmeddelande.

Tänk till exempel på följande mappstruktur i ett paket:

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

När du installerar det här paketet i ett projekt som är avsett för .NET Framework 4.6 installerar NuGet sammansättningen i net45 mappen, eftersom det är den högsta tillgängliga versionen som är mindre än eller lika med 4.6.

Om projektet är avsett för .NET Framework 4.6.1 installerar NuGet å andra sidan sammansättningen i net461 mappen.

Om projektet är avsett för .NET Framework 4.0 och tidigare genererar NuGet ett lämpligt felmeddelande för att inte hitta den kompatibla sammansättningen.

Gruppera sammansättningar efter ramverksversion

NuGet kopierar sammansättningar från endast en enda biblioteksmapp i paketet. Anta till exempel att ett paket har följande mappstruktur:

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

När paketet installeras i ett projekt som riktar sig mot .NET Framework 4.5 MyAssembly.dll är (v2.0) den enda sammansättningen installerad. MyAssembly.Core.dll (v1.0) är inte installerat eftersom det inte finns med i net45 mappen. NuGet beter sig på det här sättet eftersom MyAssembly.Core.dll kan ha sammanfogats till version 2.0 av MyAssembly.dll.

Om du vill MyAssembly.Core.dll vara installerad för .NET Framework 4.5 placerar du en kopia i net45 mappen.

Gruppera sammansättningar efter ramverksprofil

NuGet har också stöd för att rikta in sig på en specifik ramverksprofil genom att lägga till ett bindestreck och profilnamnet i slutet av mappen.

lib{framework name}-{profile}

Profilerna som stöds är följande:

  • client: Klientprofil
  • full: Fullständig profil
  • wp:Windows Phone
  • cf: Compact Framework

Deklarera beroenden (avancerat)

När du packar en projektfil försöker NuGet automatiskt generera beroenden från projektet. Informationen i det här avsnittet om hur du använder en .nuspec-fil för att deklarera beroenden är vanligtvis endast nödvändig för avancerade scenarier.

(Version 2.0+) Du kan deklarera paketberoenden i .nuspec som motsvarar målramverket för målprojektet med hjälp <group> av element i elementet <dependencies> . Mer information finns i beroendeelementet.

Varje grupp har ett attribut med namnet targetFramework och innehåller noll eller fler <dependency> element. Dessa beroenden installeras tillsammans när målramverket är kompatibelt med projektets ramverksprofil. Se Målramverk för exakta ramverksidentifierare.

Vi rekommenderar att du använder en grupp per Target Framework Moniker (TFM) för filer i mapparna lib/ och ref/ .

I följande exempel visas olika varianter av elementet <group> :

<dependencies>

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

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

</dependencies>

Avgöra vilket NuGet-mål som ska användas

När du paketerar bibliotek som är inriktade på det bärbara klassbiblioteket kan det vara svårt att avgöra vilket NuGet-mål du ska använda i dina mappnamn och .nuspec filer, särskilt om du endast riktar in dig på en delmängd av PCL:n. Följande externa resurser hjälper dig med detta:

Innehållsfiler och PowerShell-skript

Varning

Föränderliga innehållsfiler och skriptkörningar är endast tillgängliga med packages.config formatet. De är inaktuella med alla andra format och bör inte användas för nya paket.

Med packages.configkan innehållsfiler och PowerShell-skript grupperas efter målramverk med samma mappkonvention i mapparna content och tools . Till exempel:

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

Om en ramverksmapp lämnas tom lägger NuGet inte till sammansättningsreferenser eller innehållsfiler eller kör PowerShell-skripten för det ramverket.

Anmärkning

Eftersom init.ps1 körs på lösningsnivå och inte är beroende av projektet måste det placeras direkt under tools mappen. Den ignoreras om den placeras under en ramverksmapp.