Obsługiwane rozwiązania międzyplatformowe

Nowoczesna platforma .NET obsługuje wiele systemów operacyjnych i urządzeń. Biblioteki typu open source platformy .NET są ważne, aby obsługiwać jak najwięcej deweloperów, niezależnie od tego, czy tworzą witrynę internetową ASP.NET hostowaną na platformie Azure, czy grę platformy .NET w środowisku Unity.

Obiekty docelowe platformy .NET i .NET Standard

Docelowe platformy .NET i .NET Standard to najlepszy sposób dodawania obsługi międzyplatformowej do biblioteki .NET.

  • .NET Standard to specyfikacja interfejsów API platformy .NET, które są dostępne we wszystkich implementacjach platformy .NET. Określanie wartości docelowej platformy .NET Standard umożliwia tworzenie bibliotek, które są ograniczone do używania interfejsów API w danej wersji platformy .NET Standard, co oznacza, że można go używać na wszystkich platformach, które implementują tę wersję platformy .NET Standard.
  • .NET 6-8 to implementacje platformy .NET. Każda wersja to pojedynczy produkt z jednolitym zestawem funkcji i interfejsów API, które mogą być używane w aplikacjach klasycznych systemu Windows i aplikacjach konsolowych dla wielu platform, usługach w chmurze i witrynach internetowych.

Aby uzyskać więcej informacji na temat porównywania platformy .NET z platformą .NET Standard, zobacz .NET 5 i .NET Standard.

.NET Standard

Jeśli projekt jest przeznaczony dla platformy .NET lub .NET Standard i kompiluje się pomyślnie, nie gwarantuje pomyślnego uruchomienia biblioteki na wszystkich platformach:

  • Interfejsy API specyficzne dla platformy kończą się niepowodzeniem na innych platformach. Na przykład Microsoft.Win32.Registry powiedzie się w systemie Windows i zostanie zgłoszony PlatformNotSupportedException w przypadku użycia w innym systemie operacyjnym.
  • Interfejsy API mogą zachowywać się inaczej. Na przykład interfejsy API odbicia mają różne cechy wydajności, gdy aplikacja korzysta z kompilacji przed czasem w systemie iOS lub UWP.

Napiwek

Zespół platformy .NET oferuje analizator zgodności platformy, który ułatwia odnajdywanie możliwych problemów.

✔️ Zacznij od dołączania netstandard2.0 elementu docelowego.

Większość bibliotek ogólnego przeznaczenia nie potrzebuje interfejsów API spoza platformy .NET Standard 2.0. Platforma .NET Standard 2.0 jest obsługiwana przez wszystkie nowoczesne platformy i jest zalecanym sposobem obsługi wielu platform z jednym celem. Jeśli nie musisz obsługiwać programu .NET Framework, możesz również wybrać platformę .NET Standard 2.1.

✔️ Jeśli potrzebujesz nowych interfejsów API wprowadzonych w nowoczesnej platformie .NET, dołącz net6.0 element docelowy lub nowszy.

Aplikacje platformy .NET 6 lub nowsze mogą używać netstandard2.0 elementu docelowego, więc net6.0 nie są wymagane. Należy jawnie kierować element net6.0, net7.0lub net8.0 , gdy chcesz używać nowszych interfejsów API platformy .NET.

❌ UNIKAJ dołączania netstandard1.x elementu docelowego.

Program .NET Standard 1.x jest dystrybuowany jako szczegółowy zestaw pakietów NuGet, który tworzy duży graf zależności pakietu i powoduje pobranie wielu pakietów podczas kompilowania. Nowoczesne implementacje platformy .NET obsługują platformę .NET Standard 2.0. Należy kierować program .NET Standard 1.x tylko wtedy, gdy jest to konieczne dla starszej platformy.

✔️ Czy dołączyć element docelowy netstandard2.0 , jeśli jest wymagany element docelowy netstandard1.x .

Wszystkie platformy obsługujące platformę .NET Standard 2.0 będą używać netstandard2.0 elementu docelowego i korzystać z mniejszego grafu pakietów, podczas gdy starsze platformy będą nadal działać i wracać do używania netstandard1.x elementu docelowego.

❌ Nie dołączaj elementu docelowego platformy .NET Standard, jeśli biblioteka korzysta z modelu aplikacji specyficznego dla platformy.

Na przykład biblioteka zestawów narzędzi do sterowania platformy UWP zależy od modelu aplikacji, który jest dostępny tylko dla platformy UWP. Interfejsy API specyficzne dla modelu aplikacji nie są dostępne w programie .NET Standard.

Wielowersyjność

Czasami konieczne jest uzyskanie dostępu do interfejsów API specyficznych dla platformy z bibliotek. Najlepszym sposobem wywoływania interfejsów API specyficznych dla platformy jest użycie wielowersyjnych elementów docelowych, które kompilują projekt dla wielu platform docelowych platform .NET, a nie tylko dla jednego.

Aby chronić użytkowników przed koniecznością tworzenia dla poszczególnych struktur, należy dążyć do uzyskania danych wyjściowych platformy .NET Standard oraz jednego lub większej liczby danych wyjściowych specyficznych dla platformy. W przypadku wielu elementów docelowych wszystkie zestawy są pakowane wewnątrz jednego pakietu NuGet. Użytkownicy mogą następnie odwoływać się do tego samego pakietu, a pakiet NuGet wybierze odpowiednią implementację. Biblioteka .NET Standard służy jako biblioteka rezerwowa używana wszędzie, z wyjątkiem przypadków, w których pakiet NuGet oferuje implementację specyficzną dla platformy. Wielowersyjność umożliwia korzystanie z kompilacji warunkowej w kodzie i wywoływaniu interfejsów API specyficznych dla platformy.

NuGet package with multiple assemblies

✔️ ROZWAŻ zastosowanie implementacji platformy .NET oprócz platformy .NET Standard.

Ukierunkowanie implementacji platformy .NET umożliwia wywoływanie interfejsów API specyficznych dla platformy, które znajdują się poza platformą .NET Standard.

Nie usuwaj obsługi platformy .NET Standard, gdy to zrobisz. Zamiast tego wyrzuć z implementacji i oferują interfejsy API możliwości. Dzięki temu biblioteka może być używana w dowolnym miejscu i obsługuje oświetlenie funkcji w czasie wykonywania.

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

✔️ Rozważ użycie wielu elementów docelowych, nawet jeśli kod źródłowy jest taki sam dla wszystkich obiektów docelowych, jeśli projekt ma dowolną bibliotekę lub zależności pakietów.

Pakiety zależne projektu, bezpośrednie lub podrzędne, mogą używać tych samych interfejsów API kodu w różnych wersjach zestawu zależnego na platformę docelową. Dodanie określonych obiektów docelowych gwarantuje, że użytkownicy nie muszą dodawać ani aktualizować przekierowań powiązań zestawów.

❌ UNIKAJ określania wielu elementów docelowych, a także określania wartości docelowej platformy .NET Standard, jeśli kod źródłowy jest taki sam dla wszystkich obiektów docelowych, a projekt nie ma biblioteki ani zależności pakietów.

Zestaw .NET Standard będzie automatycznie używany przez pakiet NuGet. Określanie wartości docelowej dla poszczególnych implementacji platformy .NET zwiększa *.nupkg rozmiar bez korzyści.

✔️ ROZWAŻ dodanie elementu docelowego w net462 przypadku oferowania netstandard2.0 elementu docelowego.

Korzystanie z platformy .NET Standard 2.0 z programu .NET Framework ma pewne problemy, które zostały rozwiązane w programie .NET Framework 4.7.2. Możesz ulepszyć środowisko dla deweloperów, którzy są nadal w programie .NET Framework 4.6.2 — 4.7.1, oferując im plik binarny utworzony dla programu .NET Framework 4.6.2.

✔️ CZY rozpowszechniać bibliotekę przy użyciu pakietu NuGet.

Narzędzie NuGet wybierze najlepszy element docelowy dla dewelopera i będzie chronić je przed wybraniem odpowiedniej implementacji.

✔️ Należy użyć właściwości pliku TargetFrameworks projektu, gdy jest to wielowersyjność.

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

✔️ ROZWAŻ użycie biblioteki MSBuild.Sdk.Extras w przypadku wielowersyjnych elementów przeznaczonych dla platformy UWP i platformy Xamarin, ponieważ znacznie upraszcza plik projektu.

❌ UNIKAJ zmiany nazwy zestawu lub używania różnych nazw zestawów dla każdego serwera TFM, który kompiluje biblioteka. Ze względu na zależności między bibliotekami wielowersyjność z różnymi nazwami zestawów na serwer TFM może przerwać użytkowników pakietów. Zestaw powinien mieć taką samą nazwę we wszystkich serwerach TFM.

Starsze elementy docelowe

Platforma .NET obsługuje docelowe wersje programu .NET Framework, które nie są już obsługiwane, a także platformy, które nie są już używane. Chociaż istnieje wartość umożliwiająca pracę biblioteki na jak największej liczbą miejsc docelowych, konieczność obejścia brakujących interfejsów API może zwiększyć znaczne obciążenie. Biorąc pod uwagę ich zasięg i ograniczenia, niektóre struktury nie są już warte kierowania.

❌ Nie dołączaj elementu docelowego biblioteki klas przenośnych (PCL). Na przykład portable-net45+win8+wpa81+wp8.

.NET Standard to nowoczesny sposób obsługi międzyplatformowych bibliotek .NET i zastępowania list PCLs.

❌ Nie dołączaj obiektów docelowych dla platform .NET, które nie są już obsługiwane. Na przykład , SL4. WP