Platformoverschrijdende targeting

Moderne .NET ondersteunt meerdere besturingssystemen en apparaten. Het is belangrijk dat .NET opensource-bibliotheken zoveel mogelijk ontwikkelaars ondersteunen, ongeacht of ze een ASP.NET website bouwen die wordt gehost in Azure of een .NET-game in Unity.

.NET- en .NET Standard-doelen

.NET- en .NET Standard-doelen zijn de beste manier om platformoverschrijdende ondersteuning toe te voegen aan een .NET-bibliotheek.

  • .NET Standard is een specificatie van .NET API's die beschikbaar zijn voor alle .NET-implementaties. Met .NET Standard kunt u bibliotheken produceren die zijn beperkt tot het gebruik van API's die zich in een bepaalde versie van .NET Standard bevinden. Dit betekent dat het kan worden gebruikt door alle platforms die die versie van .NET Standard implementeren.
  • .NET 6-8 zijn implementaties van .NET. Elke versie is één product met een uniforme set mogelijkheden en API's die kunnen worden gebruikt voor Windows-desktop-apps en platformoverschrijdende console-apps, cloudservices en websites.

Zie .NET 5 en .NET Standard voor meer informatie over hoe .NET Standard zich verhoudt tot .NET Standard.

.NET Standard

Als uw project is gericht op .NET of .NET Standard en wordt gecompileerd, wordt niet gegarandeerd dat de bibliotheek op alle platforms wordt uitgevoerd:

  • Platformspecifieke API's mislukken op andere platforms. Slaagt bijvoorbeeld Microsoft.Win32.Registry in Windows en genereert PlatformNotSupportedException wanneer dit wordt gebruikt in een ander besturingssysteem.
  • API's kunnen zich anders gedragen. Reflectie-API's hebben bijvoorbeeld verschillende prestatiekenmerken wanneer een toepassing vooraf compilatie op iOS of UWP gebruikt.

Tip

Het .NET-team biedt een platformcompatibiliteitsanalyse waarmee u mogelijke problemen kunt detecteren.

✔️ BEGIN met het opnemen van een netstandard2.0 doel.

De meeste bibliotheken voor algemeen gebruik hebben geen API's nodig buiten .NET Standard 2.0. .NET Standard 2.0 wordt ondersteund door alle moderne platforms en is de aanbevolen manier om meerdere platforms met één doel te ondersteunen. Als u .NET Framework niet hoeft te ondersteunen, kunt u zich ook richten op .NET Standard 2.1.

✔️ Neem een net6.0 doel of hoger op als u nieuwe API's nodig hebt die zijn geïntroduceerd in een moderne .NET.

.NET 6- en hoger-apps kunnen een netstandard2.0 doel gebruiken, dus net6.0 is niet vereist. U moet zich expliciet richten op net6.0of net7.0net8.0 wanneer u nieuwere .NET-API's wilt gebruiken.

❌ VERMIJD het opnemen van een netstandard1.x doel.

.NET Standard 1.x wordt gedistribueerd als een gedetailleerde set NuGet-pakketten, die een grote pakketafhankelijkheidsgrafiek maakt en resulteert in het downloaden van veel pakketten bij het bouwen. Moderne .NET-implementaties ondersteunen .NET Standard 2.0. U moet alleen .NET Standard 1.x targeten als u specifiek op een ouder platform moet richten.

✔️ Neem een netstandard2.0 doel op als u een netstandard1.x doel nodig hebt.

Alle platforms die .NET Standard 2.0 ondersteunen, gebruiken het netstandard2.0 doel en profiteren van een kleinere pakketgrafiek, terwijl oudere platforms nog steeds werken en terugvallen op het gebruik van het netstandard1.x doel.

❌ Neem geen .NET Standard-doel op als de bibliotheek afhankelijk is van een platformspecifiek app-model.

Een UWP-bibliotheek voor beheertoolkits is bijvoorbeeld afhankelijk van een app-model dat alleen beschikbaar is op UWP. App-modelspecifieke API's zijn niet beschikbaar in .NET Standard.

Meerdere targeting

Soms moet u toegang krijgen tot frameworkspecifieke API's vanuit uw bibliotheken. De beste manier om frameworkspecifieke API's aan te roepen, is door multi-targeting te gebruiken, waarmee uw project wordt gebouwd voor veel .NET-doelframeworks in plaats van voor slechts één.

Als u uw consumenten wilt beschermen tegen het bouwen voor afzonderlijke frameworks, moet u streven naar een .NET Standard-uitvoer plus een of meer frameworkspecifieke uitvoer. Met meerdere doelen worden alle assembly's verpakt in één NuGet-pakket. Consumenten kunnen vervolgens verwijzen naar hetzelfde pakket en NuGet kiest de juiste implementatie. Uw .NET Standard-bibliotheek fungeert als de terugvalbibliotheek die overal wordt gebruikt, met uitzondering van de gevallen waarin uw NuGet-pakket een frameworkspecifieke implementatie biedt. Met meerdere targeting kunt u voorwaardelijke compilatie gebruiken in uw code en frameworkspecifieke API's aanroepen.

NuGet package with multiple assemblies

✔️ OVERWEEG naast .NET Standard.NET-implementaties te richten.

Met .NET-implementaties kunt u platformspecifieke API's aanroepen die zich buiten .NET Standard bevinden.

Verwijder geen ondersteuning voor .NET Standard wanneer u dit doet. In plaats daarvan kunt u de implementatie weggooien en mogelijkheids-API's aanbieden. Op deze manier kan uw bibliotheek overal worden gebruikt en ondersteuning bieden voor runtime-verlichting van functies.

public static class GpsLocation
{
    // This project uses multi-targeting to expose device-specific APIs to .NET Standard.
    public static async Task<(double latitude, double longitude)> GetCoordinatesAsync()
    {
#if NET462
        return CallDotNetFrameworkApi();
#elif WINDOWS_UWP
        return CallUwpApi();
#else
        throw new PlatformNotSupportedException();
#endif
    }

    // Allows callers to check without having to catch PlatformNotSupportedException
    // or replicating the OS check.
    public static bool IsSupported
    {
        get
        {
#if NET462 || WINDOWS_UWP
            return true;
#else
            return false;
#endif
        }
    }
}

✔️ OVERWEEG meerdere doelen, zelfs als uw broncode hetzelfde is voor alle doelen, wanneer uw project bibliotheek- of pakketafhankelijkheden heeft.

De afhankelijke pakketten van uw project, hetzij direct of downstream, kunnen dezelfde code-API's gebruiken terwijl ze zijn verpakt in verschillende versies van de afhankelijke assembly per doelframework. Het toevoegen van specifieke doelen zorgt ervoor dat uw gebruikers hun assemblybindingsomleidingen niet hoeven toe te voegen of bij te werken.

❌ VERMIJD multi-targeting en doel .NET Standard, als uw broncode hetzelfde is voor alle doelen en uw project geen bibliotheek- of pakketafhankelijkheden heeft.

De .NET Standard-assembly wordt automatisch gebruikt door NuGet. Door afzonderlijke .NET-implementaties te richten, wordt de *.nupkg grootte voor geen enkel voordeel vergroot.

✔️ OVERWEEG een doel toe te voegen voor net462 wanneer u een netstandard2.0 doel aanbiedt.

Het gebruik van .NET Standard 2.0 van .NET Framework heeft enkele problemen die zijn opgelost in .NET Framework 4.7.2. U kunt de ervaring voor ontwikkelaars die zich nog steeds op .NET Framework 4.6.2 - 4.7.1 bevinden, verbeteren door ze een binair bestand te bieden dat is gebouwd voor .NET Framework 4.6.2.

✔️ Distribueer uw bibliotheek met behulp van een NuGet-pakket.

NuGet selecteert het beste doel voor de ontwikkelaar en afschermt ze die de juiste implementatie moeten kiezen.

✔️ Gebruik de eigenschap van TargetFrameworks een projectbestand wanneer meerdere doelgroepen worden gebruikt.

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <!-- This project will output netstandard2.0 and net462 assemblies -->
    <TargetFrameworks>netstandard2.0;net462</TargetFrameworks>
  </PropertyGroup>
</Project>

✔️ OVERWEEG MSBuild.Sdk.Extras te gebruiken wanneer meerdere doelgroepen voor UWP en Xamarin worden gebruikt, omdat het uw projectbestand aanzienlijk vereenvoudigt.

❌ VERMIJD het wijzigen van de assemblynaam of het gebruik van verschillende assemblynamen voor elke TFM die door uw bibliotheek wordt gecompileerd. Vanwege afhankelijkheden tussen bibliotheken kan multi-targeting met verschillende assemblynamen per TFM pakketgebruikers breken. Een assembly moet dezelfde naam hebben voor alle TFM's.

Oudere doelen

.NET biedt ondersteuning voor versies van .NET Framework die niet meer worden ondersteund en platformen die niet meer algemeen worden gebruikt. Hoewel er waarde is om uw bibliotheek zoveel mogelijk doelen te laten uitvoeren, kan het veel overhead opleveren om ontbrekende API's te omzeilen. Gezien hun bereik en beperkingen, zijn bepaalde frameworks niet langer de moeite waard om zich te richten.

❌ NEEM GEEN PCL-doel (Portable Class Library) op. Bijvoorbeeld: portable-net45+win8+wpa81+wp8.

.NET Standard is de moderne manier om platformoverschrijdende .NET-bibliotheken te ondersteunen en PCL's te vervangen.

❌ Neem geen doelen op voor .NET-platforms die niet meer worden ondersteund. Bijvoorbeeld, SL4. WP