Zmiany powodujące niezgodność

Ważne jest, aby biblioteka platformy .NET znalazła równowagę między stabilnością istniejących użytkowników a innowacjami w przyszłości. Autorzy bibliotek pochylili się nad refaktoryzowaniem i przemyśleniem kodu, dopóki nie będzie to idealne, ale przerywanie istniejących użytkowników ma negatywny wpływ, zwłaszcza w przypadku bibliotek niskiego poziomu.

Typy projektów i zmiany powodujące niezgodność

Sposób użycia biblioteki przez społeczność platformy .NET zmienia wpływ zmian powodujących niezgodność w deweloperach użytkowników końcowych.

  • Biblioteki niskiego i środkowego poziomu, takie jak serializator, analizator HTML, maper obiektów bazy danych lub struktura internetowa, są najbardziej dotknięte zmianami powodujących niezgodność.

    Pakiety bloków konstrukcyjnych są używane przez deweloperów końcowych do tworzenia aplikacji i innych bibliotek jako zależności NuGet. Na przykład tworzysz aplikację i używasz klienta open source do wywoływania usługi internetowej. Aktualizacja powodująca niezgodność dla zależności używanej przez klienta nie jest czymś, co można naprawić. Jest to klient typu open source, który musi zostać zmieniony i nie masz nad nim żadnej kontroli. Musisz znaleźć zgodne wersje bibliotek lub przesłać poprawkę do biblioteki klienta i poczekać na nową wersję. Najgorszą sytuacją jest użycie dwóch bibliotek, które zależą od wzajemnie niezgodnych wersji trzeciej biblioteki.

  • Biblioteki wysokiego poziomu, takie jak zestaw kontrolek interfejsu użytkownika, są mniej wrażliwe na zmiany powodujące niezgodność.

    Biblioteki wysokiego poziomu są bezpośrednio przywołyne w aplikacji użytkownika końcowego. W przypadku wystąpienia zmian powodujących niezgodność deweloper może zdecydować się na aktualizację do najnowszej wersji lub zmodyfikować aplikację, aby mogła pracować ze zmianą powodującą niezgodność.

✔️ Zastanów się, jak będzie używana biblioteka. Jaki wpływ będą miały zmiany powodujące niezgodność w aplikacjach i bibliotekach korzystających z nich?

✔️ Zminimalizuj zmiany powodujące niezgodność podczas tworzenia biblioteki platformy .NET niskiego poziomu.

✔️ ROZWAŻ opublikowanie ważnego ponownego zapisywania biblioteki jako nowego pakietu NuGet.

Typy zmian powodujących niezgodność

Zmiany powodujące niezgodność dzielą się na różne kategorie i nie mają równego wpływu.

Zmiana powodująca niezgodność źródła

Zmiana powodująca niezgodność źródła nie ma wpływu na wykonywanie programu, ale spowoduje błędy kompilacji przy następnym ponownym skompilowanej aplikacji. Na przykład nowe przeciążenie może utworzyć niejednoznaczność wywołań metod, które były jednoznaczne wcześniej, lub zmieniona nazwa parametru spowoduje przerwanie wywołań używających nazwanych parametrów.

public class Task
{
    // Adding a type called Task could conflict with System.Threading.Tasks.Task at compilation
}

Ponieważ zmiana powodująca niezgodność źródła jest szkodliwa tylko wtedy, gdy deweloperzy ponownie skompilują swoje aplikacje, jest to najmniej destrukcyjna zmiana powodująca niezgodność. Deweloperzy mogą łatwo naprawić własny uszkodzony kod źródłowy.

Zmiana powodująca niezgodność zachowania

Zmiany zachowania są najczęstszym typem zmiany powodującej niezgodność: prawie każda zmiana zachowania może spowodować błąd logiki dla użytkownika. Zmiany w bibliotece, takie jak sygnatury metod, wyjątki zgłaszane lub wejściowe lub wyjściowe formaty danych, mogą mieć negatywny wpływ na użytkowników biblioteki. Nawet poprawka usterek może kwalifikować się jako zmiana powodująca niezgodność, jeśli użytkownicy polegali na wcześniej uszkodzonym zachowaniu.

Dodawanie funkcji i poprawianie złych zachowań jest dobrą rzeczą, ale bez opieki może to utrudnić istniejącym użytkownikom uaktualnienie. Jednym z podejść ułatwiających deweloperom radzenie sobie ze zmianami powodującymi niezgodność zachowania jest ukrycie ich za ustawieniami. Ustawienia umożliwić deweloperom aktualizowanie do najnowszej wersji biblioteki, jednocześnie decydując się na rezygnację z zmian powodujących niezgodność. Ta strategia pozwala deweloperom na aktualną konieczność dostosowywania kodu z upływem czasu.

Na przykład ASP.NET Core MVC ma koncepcję wersji zgodności, która modyfikuje funkcje włączone i wyłączone w systemie MvcOptions.

✔️ ROZWAŻ pozostawienie nowych funkcji domyślnie wyłączonych, jeśli mają wpływ na istniejących użytkowników, a deweloperzy mogą zdecydować się na tę funkcję za pomocą ustawienia.

Aby uzyskać więcej informacji na temat zmian powodujących niezgodność zachowania w interfejsach API platformy .NET, zobacz Zgodność zmian behawioralnych platformy .NET.

Zmiana powodująca niezgodność binarną

Zmiana powodująca niezgodność binarna występuje, gdy zmienisz publiczny interfejs API biblioteki, więc zestawy skompilowane względem starszych wersji biblioteki nie będą już w stanie wywołać interfejsu API. Na przykład zmiana podpisu metody przez dodanie nowego parametru spowoduje skompilowanie zestawów względem starszej wersji biblioteki w celu wyrzucenia elementu MissingMethodException.

Zmiana powodująca niezgodność binarną może również przerwać cały zestaw. Zmiana nazwy zestawu AssemblyName przy użyciu spowoduje zmianę tożsamości zestawu, tak jak dodanie, usunięcie lub zmiana silnego klucza nazewnictwa zestawu. Zmiana tożsamości zestawu spowoduje przerwanie wszystkich skompilowanych kodu, który go używa.

❌ NIE ZMIENIAJ nazwy zestawu.

❌ NIE dodawaj, usuwaj ani zmieniaj silnego klucza nazewnictwa.

✔️ ROZWAŻ użycie abstrakcyjnych klas bazowych zamiast interfejsów.

Dodanie dowolnego elementu do interfejsu spowoduje, że istniejące typy implementujące go kończą się niepowodzeniem. Abstrakcyjna klasa bazowa umożliwia dodanie domyślnej implementacji wirtualnej.

✔️ ROZWAŻ umieszczenie ObsoleteAttribute elementów w typach i elementach członkowskich, które mają być usuwane. Atrybut powinien mieć instrukcje dotyczące aktualizowania kodu, aby nie używać przestarzałego interfejsu API.

Kod, który wywołuje typy i metody za pomocą ObsoleteAttribute polecenia , spowoduje wygenerowanie ostrzeżenia kompilacji z komunikatem dostarczonym do atrybutu. Ostrzeżenia dają osobom, które używają przestarzałego czasu powierzchni interfejsu API do migracji, aby po usunięciu przestarzałego interfejsu API większość z nich nie korzystała.

public class Document
{
    [Obsolete("LoadDocument(string) is obsolete. Use LoadDocument(Uri) instead.")]
    public static Document LoadDocument(string uri)
    {
        return LoadDocument(new Uri(uri));
    }

    public static Document LoadDocument(Uri uri)
    {
        // Load the document
    }
}

✔️ ROZWAŻ przechowywanie typów i metod ObsoleteAttribute bezterminowo w bibliotekach niskiego i średniego poziomu.

Usuwanie interfejsów API jest zmianą powodującą niezgodność binarną. Rozważanie utrzymania przestarzałych typów i metod, jeśli ich utrzymywanie jest niskie i nie dodaje dużej ilości długu technicznego do biblioteki. Brak usuwania typów i metod może pomóc uniknąć najgorszych scenariuszy wymienionych powyżej.

Aby uzyskać więcej informacji na temat zmian interfejsu API platformy .NET, które przerywają zgodność binarną, zobacz Zgodność kontraktu publicznego platformy .NET.

Zobacz też