Supporto di più versioni di .NETSupport multiple .NET versions

Molte librerie hanno come destinazione una versione specifica di .NET Framework.Many libraries target a specific version of the .NET Framework. Ad esempio, si potrebbe disporre di una versione della libreria specifica per UWP e di un'altra versione che sfrutta le funzionalità di .NET Framework 4.6.For example, you might have one version of your library that's specific to UWP, and another version that takes advantage of features in .NET Framework 4.6. Per risolvere questo problema, NuGet supporta l'inserimento di più versioni della stessa libreria in un singolo pacchetto.To accommodate this, NuGet supports putting multiple versions of the same library in a single package.

Questo articolo descrive il layout di un pacchetto NuGet, indipendentemente dal modo in cui vengono creati il pacchetto o gli assembly, ovvero il layout è lo stesso se si usano più file con estensione csproj non di tipo SDK e un file personalizzato con estensione nuspec o un singolo file csproj di tipo SDK con più destinazioni.This article describes the layout of a NuGet package, regardless of how the package or assemblies are built (that is, the layout is the same whether using multiple non-SDK-style .csproj files and a custom .nuspec file, or a single multi-targetecd SDK-style .csproj). Per un progetto di tipo SDK, le destinazioni per pack di NuGet conoscono il layout previsto per il pacchetto e automatizzano l'inserimento degli assembly nelle cartelle lib corrette e la creazione dei gruppi di dipendenze per ogni framework di destinazione (TFM).For an SDK-style project, NuGet pack targets knows how the package must be layed out and automates putting the assemblies in the correct lib folders and creating dependency groups for each target framework (TFM). Per istruzioni dettagliate, vedere Supportare più versioni di .NET Framework nel file di progetto.For detailed instructions, see Support multiple .NET Framework versions in your project file.

È necessario impostare manualmente il layout del pacchetto come descritto in questo articolo quando si usa il metodo della directory di lavoro basata sulle convenzioni descritto in Creazione di un pacchetto.You must manually lay out the package as described in this article when using the convention-based working directory method described in Creating a package. Per un progetto di tipo SDK, è consigliabile usare il metodo automatico, ma è anche possibile scegliere di impostare manualmente il layout del pacchetto come descritto in questo articolo.For an SDK-style project, the automated method is recommended, but you may also choose to manually lay out the package as described in this article.

Struttura di cartelle della versione del frameworkFramework version folder structure

Quando si compila un pacchetto che contiene solo una versione di una libreria o che ha come destinazione più framework, si creano sempre sottocartelle in lib usando nomi di framework diversi con distinzione tra maiuscole e minuscole in base alla convenzione seguente:When building a package that contains only one version of a library or target multiple frameworks, you always make subfolders under lib using different case-sensitive framework names with the following convention:

lib\{framework name}[{version}]

Per un elenco completo dei nomi supportati, vedere le informazioni di riferimento sui framework di destinazione.For a complete list of supported names, see the Target Frameworks reference.

Non si deve mai disporre di una versione della libreria che non sia specifica di un framework e che sia inserita direttamente nella cartella lib radiceYou should never have a version of the library that is not specific to a framework and placed directly in the root lib folder. (questa funzionalità è supportata solo con packages.config).(This capability was supported only with packages.config). Così facendo, si renderebbe la libreria compatibile con qualsiasi framework di destinazione consentendone l'installazione in qualunque posizione, con probabili errori di runtime imprevisti.Doing so would make the library compatible with any target framework and allow it to be installed anywhere, likely resulting in unexpected runtime errors. L'aggiunta di assembly nella cartella radice (ad esempio lib\abc.dll) o nelle sottocartelle (ad esempio lib\abc\abc.dll) è deprecata e viene ignorata quando si usa il formato PackagesReference.Adding assemblies in the root folder (such as lib\abc.dll) or subfolders (such as lib\abc\abc.dll) has been deprecated and is ignored when using the PackagesReference format.

Ad esempio, la struttura di cartelle seguente supporta quattro versioni di un assembly che sono specifiche del framework:For example, the following folder structure supports four versions of an assembly that are framework-specific:

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

Per includere facilmente tutti i file durante la compilazione del pacchetto, usare un carattere jolly ** ricorsivo nella sezione <files> di .nuspec:To easily include all these files when building the package, use a recursive ** wildcard in the <files> section of your .nuspec:

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

Cartelle specifiche dell'architetturaArchitecture-specific folders

Se si dispone di assembly specifici dell'architettura, vale a dire assembly distinti che hanno come destinazione ARM, x86 e x64, è necessario inserirli in una cartella denominata runtimes all'interno di sottocartelle denominate {platform}-{architecture}\lib\{framework} o {platform}-{architecture}\native.If you have architecture-specific assemblies, that is, separate assemblies that target ARM, x86, and x64, you must place them in a folder named runtimes within sub-folders named {platform}-{architecture}\lib\{framework} or {platform}-{architecture}\native. Ad esempio, la struttura di cartelle seguente potrebbe contenere sia DLL native che gestite che hanno come destinazione Windows 10 e il framework uap10.0:For example, the following folder structure would accommodate both native and managed DLLs targeting Windows 10 and the uap10.0 framework:

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

Poiché questi assembly saranno disponibili solo in fase di esecuzione, per fornire l'assembly corrispondente anche in fase di compilazione, l'assembly AnyCPU deve essere presente nella cartella /ref{tfm}.These assemblies will only be available at runtime, so if you want to provide the corresponding compile time assembly as well then have AnyCPU assembly in /ref{tfm} folder.

Ricordare che, poiché NuGet seleziona sempre questi asset di compilazione o di runtime da una sola cartella, se sono presenti asset compatibili in /ref, /lib non verrà considerata per l'aggiunta di assembly in fase di compilazione.Please note, NuGet always picks these compile or runtime assets from one folder so if there are some compatible assets from /ref then /lib will be ignored to add compile-time assemblies. Analogamente, se sono presenti asset compatibili in /runtime, /lib verrà ignorata anche per il runtime.Similarly, if there are some compatbile assets from /runtime then also /lib will be ignored for runtime.

Vedere Creare pacchetti UWP per un esempio di riferimento a questi file nel manifesto .nuspec.See Create UWP Packages for an example of referencing these files in the .nuspec manifest.

Vedere anche Packing a Windows store app component with NuGet (Creazione di un pacchetto di un componente app di Windows Store con NuGet)Also, see Packing a Windows store app component with NuGet

Corrispondenza tra le versioni di assembly e il framework di destinazione in un progettoMatching assembly versions and the target framework in a project

Quando NuGet installa un pacchetto che dispone di più versioni di assembly, tenta di associare il nome del framework dell'assembly con il framework di destinazione del progetto.When NuGet installs a package that has multiple assembly versions, it tries to match the framework name of the assembly with the target framework of the project.

Se non viene trovata una corrispondenza, NuGet copia l'assembly per la versione più alta inferiore o uguale al framework di destinazione del progetto, se disponibile.If a match is not found, NuGet copies the assembly for the highest version that is less than or equal to the project's target framework, if available. Se non viene trovato un assembly compatibile, NuGet restituisce un messaggio di errore appropriato.If no compatible assembly is found, NuGet returns an appropriate error message.

Si consideri ad esempio la struttura di cartelle seguente in un pacchetto:For example, consider the following folder structure in a package:

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

Quando si installa questo pacchetto in un progetto che ha come destinazione .NET Framework 4.6, NuGet installa l'assembly nella cartella net45, trattandosi della versione più alta disponibile inferiore o uguale alla versione 4.6.When installing this package in a project that targets .NET Framework 4.6, NuGet installs the assembly in the net45 folder, because that's the highest available version that's less than or equal to 4.6.

Se il progetto ha come destinazione .NET Framework 4.6.1, invece, NuGet installa l'assembly nella cartella net461.If the project targets .NET Framework 4.6.1, on the other hand, NuGet installs the assembly in the net461 folder.

Se il progetto ha come destinazione .NET Framework 4.0 e versioni precedenti, NuGet genera un messaggio di errore appropriato per non avere trovato un assembly compatibile.If the project targets .NET framework 4.0 and earlier, NuGet throws an appropriate error message for not finding the compatible assembly.

Raggruppamento di assembly per versione del frameworkGrouping assemblies by framework version

NuGet copia gli assembly solo da una singola cartella di libreria nel pacchetto.NuGet copies assemblies from only a single library folder in the package. Si supponga ad esempio che un pacchetto abbia la struttura di cartelle seguente:For example, suppose a package has the following folder structure:

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

Quando il pacchetto viene installato in un progetto che ha come destinazione .NET Framework 4.5, MyAssembly.dll (v2.0) è l'unico assembly installato.When the package is installed in a project that targets .NET Framework 4.5, MyAssembly.dll (v2.0) is the only assembly installed. MyAssembly.Core.dll (v1.0) non è installato perché non è elencato nella cartella net45.MyAssembly.Core.dll (v1.0) is not installed because it's not listed in the net45 folder. NuGet ha questo comportamento perché MyAssembly.Core.dll potrebbe essere stato unito nella versione 2.0 di MyAssembly.dll.NuGet behaves this way because MyAssembly.Core.dll might have merged into version 2.0 of MyAssembly.dll.

Se si vuole che MyAssembly.Core.dll sia installato per .NET Framework 4.5, inserire una copia nella cartella net45.If you want MyAssembly.Core.dll to be installed for .NET Framework 4.5, place a copy in the net45 folder.

Raggruppamento di assembly per profilo del frameworkGrouping assemblies by framework profile

NuGet supporta anche la selezione di uno specifico profilo del framework come destinazione accodando un trattino e il nome del profilo alla fine della cartella.NuGet also supports targeting a specific framework profile by appending a dash and the profile name to the end of the folder.

lib\{framework name}-{profile}

I profili supportati sono i seguenti:The supported profiles are as follows:

  • client: Client Profileclient: Client Profile
  • full: Full Profilefull: Full Profile
  • wp: Windows Phonewp: Windows Phone
  • cf: Compact Frameworkcf: Compact Framework

Dichiarazione delle dipendenze (scenari avanzati)Declaring dependencies (Advanced)

Quando si crea un pacchetto per il file di progetto, NuGet tenta di generare automaticamente le dipendenze dal progetto.When packing a project file, NuGet tries to automatically generate the dependencies from the project. Le informazioni contenute in questa sezione sull'uso di un file con estensione nuspec per dichiarare le dipendenze sono in genere necessarie solo per gli scenari avanzati.The information in this section about using a .nuspec file to declare dependencies is typically necessary for advanced scenarios only.

(Versione 2.0 +) È possibile dichiarare le dipendenze del pacchetto nel file nuspec corrispondente al framework di destinazione del progetto di destinazione usando elementi <group> all'interno dell'elemento <dependencies>.(Version 2.0+) You can declare package dependencies in the .nuspec corresponding to the target framework of the target project using <group> elements within the <dependencies> element. Per altre informazioni, vedere Elemento dependencies.For more information, see dependencies element.

Ogni gruppo ha un attributo denominato targetFramework e contiene zero o più elementi <dependency>.Each group has an attribute named targetFramework and contains zero or more <dependency> elements. Tali dipendenze vengono installate insieme quando il framework di destinazione è compatibile con il profilo di framework del progetto.Those dependencies are installed together when the target framework is compatible with the project's framework profile. Vedere Framework di destinazione per gli identificatori di framework esatti.See Target frameworks for the exact framework identifiers.

Si consiglia di usare un gruppo per ogni moniker framework di destinazione (TFM) per i file nelle cartelle lib/ e ref/ .We recommend using one group per Target Framework Moniker (TFM) for files in the lib/ and ref/ folders.

L'esempio seguente mostra variazioni diverse dell'elemento <group>:The following example shows different variations of the <group> element:

<dependencies>

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

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

</dependencies>

Determinazione della destinazione NuGet da usareDetermining which NuGet target to use

Quando si inseriscono in un pacchetto librerie che hanno come destinazione la libreria di classi portabile, può essere difficile determinare quale destinazione NuGet usare nei nomi delle cartelle e nel file .nuspec, in particolare se la destinazione è solo un subset della libreria di classi portabile.When packaging libraries targeting the Portable Class Library it can be tricky to determine which NuGet target you should use in your folder names and .nuspec file, especially if targeting only a subset of the PCL. Le risorse esterne seguenti possono essere di aiuto:The following external resources will help you with this:

File di contenuto e script PowerShellContent files and PowerShell scripts

Avviso

I file di contenuto modificabili e l'esecuzione degli script sono disponibili solo con il formato packages.config. Sono deprecati per tutti gli altri formati e non dovrebbero essere usati per i nuovi pacchetti.Mutable content files and script execution are available with the packages.config format only; they are deprecated with all other formats and should not be used for any new packages.

Con packages.config, i file di contenuto e gli script PowerShell possono essere raggruppati per framework di destinazione usando la stessa convenzione di cartelle all'interno delle cartelle content e tools.With packages.config, content files and PowerShell scripts can be grouped by target framework using the same folder convention inside the content and tools folders. Ad esempio:For example:

\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 una cartella framework viene lasciata vuota, NuGet non aggiunge riferimenti ad assembly o file di contenuto né esegue script PowerShell per tale framework.If a framework folder is left empty, NuGet doesn't add assembly references or content files or run the PowerShell scripts for that framework.

Nota

Poiché init.ps1 viene eseguito a livello di soluzione e indipendentemente dal progetto, deve essere inserito direttamente sotto la cartella tools.Because init.ps1 is executed at the solution level and not dependent on project, it must be placed directly under the tools folder. Viene ignorato se inserito in una cartella framework.It's ignored if placed under a framework folder.