2016-01-05 37 views
21

Come si impacchetta una libreria .NET portatile in un modo moderno e generico? Supponiamo di avere un singolo assembly AnyCPU che desidero rendere disponibile a qualsiasi piattaforma .NET che supporti la superficie dell'API .NET Core, ad esempio .NET Framework 4.6 e Universal Windows Platform.Come impacchettare una libreria .NET portatile con targeting .NET Core?

Si tratta di una serie di domande e risposte che documentano le mie scoperte sul tema del pacchetto di authoring moderna NuGet, concentrandosi in particolare sulle modifiche introdotte con NuGet 3. Si può anche essere interessati a alcune domande correlate:

risposta

12

Questa risposta costruisce sulla principles used to package libraries targeting the .NET Framework. Leggi prima la risposta collegata per capire meglio quanto segue.

di pubblicare la libreria portabile .NET, è necessario creare un pacchetto NuGet con la seguente struttura:

\---lib 
    \---dotnet 
      MyPortableLibrary.dll 
      MyPortableLibrary.pdb 
      MyPortableLibrary.XML 

Tutti e tre i file verranno da directory di output di compilazione del progetto sotto la configurazione di rilascio di generazione.

La directory dotnet nella struttura sopra riportata ha un significato speciale: indica a NuGet che i file nella directory devono essere utilizzati su qualsiasi piattaforma compatibile con tutte le dipendenze del pacchetto. Pertanto, il tuo pacchetto è automaticamente utilizzabile su qualsiasi piattaforma .NET che supporti tutte le tue dipendenze (ad esempio .NET Core).

Il passaggio successivo cruciale è determinare l'elenco delle dipendenze. A causa di a package management issue non è possibile dichiarare semplicemente una dipendenza su .NET Core stesso (.NET Core è la superficie API condivisa da tutte le piattaforme .NET). Invece, è necessario determinare manualmente ciascuna dipendenza del componente .NET Core e aggiungerla al file nuspec.

Il processo di rilevamento delle dipendenze per i pacchetti base .NET si compone di due fasi:

  1. determinare l'assembly .NET fondamentali a cui fa riferimento la libreria.
  2. Determinare i pacchetti NuGet che contengono questi assembly.

Visual Studio non fornisce le informazioni necessarie. Invece, è necessario creare la libreria e ispezionare il file DLL risultante. Il seguente script PowerShell visualizzerà i riferimenti di un assembly .NET:

Get-ChildItem MyPortableLibrary.dll | % { [Reflection.Assembly]::LoadFile($_.FullName).GetReferencedAssemblies() | % { $_.Name + ".dll" } } 

L'output di questo comando sarà un elenco di nomi di assemblaggio, per esempio:

System.Runtime.dll 
System.Resources.ResourceManager.dll 
System.Numerics.Vectors.dll 

Dopo aver ottenuto la lista , aprire il file project.lock.json nella directory del progetto.Questo file contiene informazioni su tutti i pacchetti NuGet utilizzati dal progetto. Troverete, tra gli altri dati, i vari blocchi di JSON come il seguente:

"System.Numerics.Vectors/4.1.0": { 
    "dependencies": { 
     "System.Globalization": "[4.0.10,)", 
     "System.Resources.ResourceManager": "[4.0.0,)", 
     "System.Runtime": "[4.0.20,)", 
     "System.Runtime.Extensions": "[4.0.10,)" 
    }, 
    "frameworkAssemblies": [ 
     "mscorlib", 
     "System.Numerics" 
    ], 
    "compile": { 
     "ref/net46/System.Numerics.Vectors.dll": {} 
    }, 
    "runtime": { 
     "lib/net46/System.Numerics.Vectors.dll": {} 
    } 
}, 

Questo blocco di JSON indica che i file di montaggio elencate nella sezione "Compila" sono forniti dal pacchetto elencato nel valore di livello superiore (System.Numerics.Vectors versione 4.1.0). Utilizzare queste informazioni per associare ogni assembly di riferimento a un pacchetto NuGet. Si noti che mentre i nomi di pacchetti e assiemi sono spesso uguali, questo non è sempre il caso!

Per tutti i pacchetti NuGet che non fanno parte di .NET Core, è possibile saltare il processo di cui sopra come già si conosce il pacchetto esatto da cui si ha una dipendenza. La logica di rilevamento delle dipendenze qui descritta è necessaria solo perché non è possibile dichiarare una dipendenza direttamente su .NET Core (il pacchetto Microsoft.NETCore) a causa del problema sopra riportato.

Ora semplicemente elencare tutte le dipendenze nel file nuspec, sulla base del seguente esempio:

<?xml version="1.0"?> 
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd"> 
    <metadata minClientVersion="3.2"> 
     <id>Example.MyPortableLibrary</id> 
     <version>1.0.0</version> 
     <authors>Firstname Lastname</authors> 
     <description>Example of a portable library with NuGet package dependencies.</description> 
     <dependencies> 
      <dependency id="System.Numerics.Vectors" version="4.1.0" /> 
      <dependency id="System.Resources.ResourceManager" version="4.0.0" /> 
      <dependency id="System.Runtime" version="4.0.20" /> 
     </dependencies> 
    </metadata> 
    <files> 
     <file src="..\bin\Release\MyPortableLibrary.*" target="lib\dotnet" /> 
    </files> 
</package> 

Questo è tutto! Il pacchetto risultante è utilizzabile su qualsiasi piattaforma .NET compatibile, come .NET Framework 4.6 o Universal Windows Platform. Ricordarsi di creare la soluzione utilizzando la configurazione di rilascio prima di creare il pacchetto NuGet.

Una libreria di esempio e i relativi file di imballaggio sono available on GitHub. La soluzione corrispondente a questa risposta è PortableLibrary.

Fare riferimento a Lucian Wischik's blog per un'immersione più profonda nella logica che opera su tali pacchetti NuGet.

+0

https://www.nuget.org/packages/NuSpec.ReferenceGenerator/2.0.0-beta-bld01 – eschneider

+2

mi sembra che questa risposta sia obsoleta, ora è 'lib \ nestandard1.5' o 1.6 e così su, ho ragione? – Omu

+0

@Omu, sei corretto. E il comando powershell non funziona e fornisce un "Eccezione chiamata" LoadFile "con argomenti" 1 ":" Questo assembly è costruito da un runtime più recente del runtime attualmente caricato e non può essere caricato. "Questa risposta richiede aggiornamento o cancellazione –

-1

Sembra esserci stato molto churn sul modo migliore per rendere portatili librerie framework .NET/pacchetti NuGet negli ultimi mesi. Se puoi aspettare un po ', ti consigliamo di leggere su .NET Standard. Immo Landwerth ha scritto un dettagliato blog post introducing the .NET Standard a settembre 2016. Il supporto per .NET Standard 2.0 in .NET Core è expected to arrive in early 2017, nello stesso periodo di tempo di Visual Studio 2017, che è attualmente in fase Release Candidate. .NET Standard 2.0 sarà implementato da .NET Framework, .NET Core e Xamarin. Comprenderà anche gli shim di compatibilità per i binari di .NET Framework, che dovrebbero facilitare l'adozione.

Aggiornamento:

Oren Novotny ha un post molto informativo su questo argomento: Multi-targeting the world: a single project to rule them all. Discute su .NET Standard e su come target multipli con Visual Studio 2017. Il post del blog è stato pubblicato prima dell'RTM di Visual Studio 2017, ma è molto utile.

Problemi correlati