Cílení na více platforem

Moderní .NET podporuje více operačních systémů a zařízení. Je důležité, aby opensourcové knihovny .NET podporovaly co nejvíce vývojářů, ať už vytvářejí ASP.NET web hostovaný v Azure, nebo hru .NET v Unity.

Cíle .NET a .NET Standard

Cíle .NET a .NET Standard jsou nejlepším způsobem, jak do knihovny .NET přidat podporu pro různé platformy.

  • .NET Standard je specifikace rozhraní .NET API, která jsou k dispozici ve všech implementacích .NET. Cílení na .NET Standard umožňuje vytvářet knihovny omezené na používání rozhraní API, která jsou v dané verzi .NET Standard, což znamená, že je použitelné pro všechny platformy, které tuto verzi .NET Standard implementují.
  • .NET 6-8 jsou implementace .NET. Každá verze je jediným produktem s jednotnou sadou funkcí a rozhraní API, která se dají použít pro desktopové aplikace Windows a konzolové aplikace pro různé platformy, cloudové služby a weby.

Další informace o porovnání rozhraní .NET se standardem .NET naleznete v tématech .NET 5 a .NET Standard.

.NET Standard

Pokud váš projekt cílí na .NET nebo .NET Standard a úspěšně se zkompiluje, nezaručuje úspěšné spuštění knihovny na všech platformách:

  • Rozhraní API specifická pro platformu selžou na jiných platformách. Například Microsoft.Win32.Registry v systému Windows proběhne úspěšně a vyvolá se PlatformNotSupportedException při použití v jakémkoli jiném operačním systému.
  • Rozhraní API se můžou chovat jinak. Například rozhraní API reflexe mají různé charakteristiky výkonu, když aplikace používá předem časovou kompilaci v iOSu nebo UPW.

Tip

Tým .NET nabízí analyzátor kompatibility platformy, který vám pomůže zjistit možné problémy.

✔️ Začněte tím, že zahrnete netstandard2.0 cíl.

Většina knihoven pro obecné účely nepotřebuje rozhraní API mimo .NET Standard 2.0. .NET Standard 2.0 je podporován všemi moderními platformami a je doporučeným způsobem, jak podporovat více platforem s jedním cílem. Pokud rozhraní .NET Framework nepotřebujete podporovat, můžete také cílit na .NET Standard 2.1.

✔️ Pokud požadujete nová rozhraní API zavedená v moderním rozhraní .NET, zahrňte net6.0 cíl nebo novější.

Aplikace .NET 6 a novější můžou používat netstandard2.0 cíl, takže net6.0 není potřeba. Měli byste explicitně cílit net6.0net7.0, nebo net8.0 pokud chcete použít novější rozhraní .NET API.

❌ Vyhněte se zahrnutí netstandard1.x cíle.

.NET Standard 1.x se distribuuje jako podrobná sada balíčků NuGet, která při sestavování vytvoří rozsáhlý graf závislostí balíčků a výsledkem je stahování velkého množství balíčků. Moderní implementace .NET podporují .NET Standard 2.0. Pokud potřebujete konkrétně cílit na starší platformu, měli byste cílit pouze na .NET Standard 1.x.

✔️ Pokud potřebujete cíl, zahrňte ho netstandard2.0netstandard1.x .

Všechny platformy podporující .NET Standard 2.0 budou používat netstandard2.0 cíl a těžit z menšího grafu balíčků, zatímco starší platformy budou i nadále fungovat a budou se vracet k používání netstandard1.x cíle.

❌ NEZAHRNUJTE cíl .NET Standard, pokud knihovna spoléhá na model aplikace pro konkrétní platformu.

Knihovna nástrojů pro ovládací sadu nástrojů pro UPW například závisí na modelu aplikace, který je dostupný jenom pro UPW. Rozhraní API pro konkrétní model aplikace nejsou v .NET Standard k dispozici.

Cílení na více verzí

Někdy potřebujete přistupovat k rozhraním API specifických pro architekturu z knihoven. Nejlepší způsob, jak volat rozhraní API specifická pro architekturu, je použít cílení na více platforem, které vytváří váš projekt pro mnoho cílových architektur .NET, a ne jenom pro jednu.

Pokud chcete chránit uživatele před tím, aby se museli vytvářet pro jednotlivé architektury, měli byste se snažit mít výstup .NET Standard plus jeden nebo více výstupů specifických pro architekturu. S více cíli se všechna sestavení zabalí do jednoho balíčku NuGet. Příjemci pak mohou odkazovat na stejný balíček a NuGet vyberou příslušnou implementaci. Vaše knihovna .NET Standard slouží jako záložní knihovna, která se používá všude, s výjimkou případů, kdy balíček NuGet nabízí implementaci specifickou pro architekturu. Cílení na více verzí umožňuje použít podmíněnou kompilaci v kódu a volat rozhraní API specifická pro architekturu.

NuGet package with multiple assemblies

✔️ ZVAŽTE cílení na implementace .NET kromě .NET Standard.

Cílení na implementace .NET umožňuje volat rozhraní API specifická pro platformu, která jsou mimo .NET Standard.

Pokud to uděláte, nezahoďte podporu pro .NET Standard. Místo toho vyvolejte rozhraní API pro implementaci a nabídku funkcí. Díky tomu můžete knihovnu používat kdekoli a podporuje spouštění funkcí.

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
        }
    }
}

✔️ ZVAŽTE cílení na více i v případě, že je zdrojový kód stejný pro všechny cíle, pokud má váš projekt jakékoli závislosti knihoven nebo balíčků.

Závislé balíčky projektu, ať už přímé nebo podřízené, můžou používat stejná rozhraní API kódu, která jsou zabalená do různých verzí závislého sestavení na cílovou architekturu. Přidání konkrétních cílů zajišťuje, že uživatelé nemusí přidávat ani aktualizovat přesměrování vazby sestavení.

❌ Vyhněte se cílení na více adres i cílení na .NET Standard, pokud je váš zdrojový kód stejný pro všechny cíle a váš projekt nemá žádné závislosti knihovny ani balíčku.

NuGet automaticky použije sestavení .NET Standard. Cílení na jednotlivé implementace .NET zvětšuje *.nupkg velikost bez výhody.

✔️ ZVAŽTE přidání cíle pro net462 , když nabízíte netstandard2.0 cíl.

Použití .NET Standard 2.0 z rozhraní .NET Framework obsahuje některé problémy, které byly vyřešeny v rozhraní .NET Framework 4.7.2. Prostředí pro vývojáře, kteří jsou stále v rozhraní .NET Framework 4.6.2 – 4.7.1, můžete vylepšit tím, že jim nabídnete binární soubor vytvořený pro rozhraní .NET Framework 4.6.2.

✔️ Distribuujte knihovnu pomocí balíčku NuGet.

NuGet vybere nejlepší cíl pro vývojáře a bude je muset vybrat příslušnou implementaci.

✔️ Při cílení na více souborů použijte vlastnost souboru TargetFrameworks projektu.

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

✔️ ZVAŽTE POUŽITÍ MSBuild.Sdk.Extras při cílení na UPW a Xamarin, protože výrazně zjednodušuje váš soubor projektu.

❌ Vyhněte se změně názvu sestavení nebo použití různých názvů sestavení pro každý TFM, který vaše knihovna zkompiluje. Vzhledem k závislostem mezi knihovnami může více cílení s různými názvy sestavení na TFM přerušit příjemce balíčků. Sestavení by mělo mít stejný název ve všech TFM.

Starší cíle

.NET podporuje cílení na verze rozhraní .NET Framework, které nejsou podporovány, a platformy, které se už běžně nepoužívají. I když existuje hodnota v tom, aby knihovna fungovala na co nejvíce cílů, může práce s chybějícími rozhraními API znamenat značné režijní náklady. Vzhledem k jejich dosažení a omezením už některé architektury nestojí za cílení.

❌ DO NOT include a Portable Class Library (PCL) target. Například portable-net45+win8+wpa81+wp8.

.NET Standard je moderní způsob, jak podporovat multiplatformní knihovny .NET a nahradit knihovny PCLS.

❌ DO NOT zahrnout cíle pro platformy .NET, které již nejsou podporovány. Například , SL4WP.