Condividi tramite


Supportare più versioni di .NET

Molte librerie hanno come destinazione una versione specifica di .NET Framework. Ad esempio, potresti avere una versione della libreria specifica per la piattaforma UWP e un'altra versione che sfrutta le funzionalità di .NET Framework 4.6. Per soddisfare questo problema, NuGet supporta l'inserimento di più versioni della stessa libreria in un singolo pacchetto.

Questo articolo descrive il layout di un pacchetto NuGet, indipendentemente dal modo in cui vengono compilati i pacchetti o gli assembly, ovvero il layout è lo stesso se si usano più file con estensione csproj non SDK e un file con estensione nuspec personalizzato o un singolo file con estensione csproj in stile SDK multi-destinazione. Per un progetto in stile SDK, le destinazioni del pacchetto NuGet conoscono il modo in cui il pacchetto deve essere inserito e automatizza l'inserimento degli assembly nelle cartelle lib corrette e la creazione di gruppi di dipendenze per ogni framework di destinazione (TFM). Per istruzioni dettagliate, vedere Supportare più versioni di .NET Framework nel file di progetto.

È necessario disporre manualmente il pacchetto come descritto in questo articolo quando si usa il metodo della directory di lavoro basato su convenzioni descritto in Creazione di un pacchetto. Per un progetto in stile SDK, è consigliabile usare il metodo automatizzato, ma è anche possibile scegliere di disporre manualmente il pacchetto come descritto in questo articolo.

Struttura delle cartelle della versione del framework

Quando si compila un pacchetto che contiene una sola versione di una libreria o che supporta più framework, si creano sempre delle sottocartelle sotto lib usando nomi di framework diversi con distinzione tra maiuscole e minuscole, seguendo questa convenzione:

lib\{framework name}[{version}]

Per un elenco completo dei nomi supportati, vedere le informazioni di riferimento sui framework di destinazione.

Non si dovrebbe mai avere una versione della libreria non specifica di un framework e inserita direttamente nella cartella radice lib . Questa funzionalità è supportata solo con packages.config. In questo modo, la libreria sarebbe compatibile con qualsiasi framework di destinazione e consentirebbe l'installazione ovunque, che potrebbe causare errori di runtime inaspettati. L'aggiunta di assembly nella cartella radice (ad esempio lib\abc.dll) o nelle sottocartelle (ad esempio lib\abc\abc.dll) è stata resa obsoleta e viene ignorata quando si usa il formato PackageReference.

Ad esempio, la struttura di cartelle seguente supporta quattro versioni di un assembly specifiche del framework:

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

Per includere facilmente tutti questi file durante la compilazione del pacchetto, usare un carattere jolly ricorsivo ** nella sezione di <files>:

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

Cartelle specifiche dell'architettura di sistema

Se sono presenti assembly specifici dell'architettura, ovvero assembly separati destinati ad ARM, x86 e x64, è necessario inserirli in una cartella denominata runtimes all'interno di sottocartelle denominate {platform}-{architecture}\lib\{framework} o {platform}-{architecture}\native. Ad esempio, la struttura di cartelle seguente supporta le DLL native e gestite destinate a Windows 10 e al uap10.0 framework:

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

Questi assembly saranno disponibili solo in fase di esecuzione, quindi se si vuole fornire anche l'assembly corrispondente per la fase di compilazione, posizionare l'assembly AnyCPU nella cartella /ref/{tfm}.

Si noti che NuGet seleziona sempre questi asset di compilazione o di runtime da una cartella, quindi se sono presenti alcuni asset compatibili da /ref allora /lib verranno ignorati per aggiungere assembly in fase di compilazione. Analogamente, se sono presenti alcuni asset compatibili da /runtimes allora verranno ignorati anche /lib per il runtime.

Vedi Creare pacchetti UWP per un esempio di riferimento a questi file nel .nuspec manifesto.

Vedi anche Creazione di un pacchetto di un componente dell'app di Windows Store con NuGet

Allineamento delle versioni degli assembly e del framework target in un progetto

Quando NuGet installa un pacchetto che contiene diverse versioni di assembly, tenta di far corrispondere il nome del framework dell'assembly con il framework di destinazione del progetto.

Se non viene trovata una corrispondenza, NuGet copia l'assembly per la versione più alta minore o uguale al framework di destinazione del progetto, se disponibile. Se non viene trovato alcun assembly compatibile, NuGet restituisce un messaggio di errore appropriato.

Si consideri ad esempio la struttura di cartelle seguente in un pacchetto:

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

Quando si installa questo pacchetto in un progetto destinato a .NET Framework 4.6, NuGet installa l'assembly nella net45 cartella, perché è la versione più elevata disponibile minore o uguale a 4.6.

Se il progetto è destinato a .NET Framework 4.6.1, NuGet installa l'assembly nella net461 cartella .

Se il progetto è destinato a .NET Framework 4.0 e versioni precedenti, NuGet genera un messaggio di errore appropriato per non trovare l'assembly compatibile.

Raggruppamento di assembly per versione del framework

NuGet copia gli assembly da una singola cartella di libreria nel pacchetto. Si supponga, ad esempio, che un pacchetto abbia la struttura di cartelle seguente:

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

Quando il pacchetto viene installato in un progetto destinato a .NET Framework 4.5, MyAssembly.dll (v2.0) è l'unico assembly installato. MyAssembly.Core.dll (v1.0) non è installato perché non è elencato nella net45 cartella . NuGet si comporta in questo modo perché MyAssembly.Core.dll potrebbe essere stato unito alla versione 2.0 di MyAssembly.dll.

Se desideri installare MyAssembly.Core.dll per .NET Framework 4.5, inserisci una copia nella cartella net45.

Raggruppamento degli assembly per profilo del framework

NuGet supporta anche la destinazione di un profilo framework specifico aggiungendo un trattino e il nome del profilo alla fine della cartella.

lib{framework name}-{profile}

I profili supportati sono i seguenti:

  • client: Profilo del cliente
  • full: profilo completo
  • wp:Windows Phone
  • cf: Compact Framework

Dichiarazione delle dipendenze (avanzate)

Durante la compressione di un file di progetto, NuGet tenta di generare automaticamente le dipendenze dal progetto. Le informazioni contenute in questa sezione sull'uso di un file con estensione nuspec per dichiarare le dipendenze sono in genere necessarie solo per scenari avanzati.

(Versione 2.0+) È possibile dichiarare le dipendenze dei pacchetti in .nuspec corrispondente al framework di destinazione del progetto di destinazione usando <group> elementi all'interno dell'elemento <dependencies> . Per ulteriori informazioni, vedere l'elemento dipendenze.

Ogni gruppo ha un attributo denominato targetFramework e contiene zero o più <dependency> elementi. Queste dipendenze vengono installate insieme quando il framework di destinazione è compatibile con il profilo del framework del progetto. Consulta Framework di destinazione per identificatori framework esatti.

Si consiglia di utilizzare un gruppo per ogni Target Framework Moniker (TFM) per i file nelle cartelle lib/ e ref/.

L'esempio seguente mostra diverse varianti dell'elemento <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>

Determinazione della destinazione NuGet da usare

Quando si creano pacchetti di librerie destinate alla Portable Class Library (PCL), può essere difficile determinare quale target NuGet usare nei nomi delle cartelle e nei file .nuspec, soprattutto se si utilizza solo un sottoinsieme della PCL. Le risorse esterne seguenti consentono di:

File di contenuto e script di PowerShell

Avvertimento

I file di contenuto modificabili e l'esecuzione di script sono disponibili solo con il packages.config formato; sono deprecati con tutti gli altri formati e non devono essere usati per i nuovi pacchetti.

Con packages.config, i file di contenuto e gli script di PowerShell possono essere raggruppati in base al framework di destinazione usando la stessa convenzione di cartella all'interno delle content cartelle e tools . Per esempio:

\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 del framework viene lasciata vuota, NuGet non aggiunge riferimenti ad assembly o file di contenuto o esegue gli script di PowerShell per tale framework.

Annotazioni

Poiché init.ps1 viene eseguito a livello di soluzione e non dipende dal progetto, deve essere inserito direttamente nella tools cartella . Viene ignorato se posizionato in una cartella del framework.