Versionierung in C#Versioning in C#

In diesem Tutorial erfahren Sie, welche Rolle die Versionierung in .NET spielt.In this tutorial you'll learn what versioning means in .NET. Außerdem erfahren Sie, welche Faktoren Sie berücksichtigen müssen, wenn Sie die Versionen Ihrer Bibliothek verwalten oder ein Upgrade auf eine neue Version der Bibliothek durchführen.You'll also learn the factors to consider when versioning your library as well as upgrading to a new version of the a library.

Erstellen von BibliothekenAuthoring Libraries

Als Entwickler, der bereits .NET-Bibliotheken für die öffentliche Verwendung erstellt hat, waren Sie bestimmt schon in Situationen, in denen Sie neue Updates implementieren mussten.As a developer who has created .NET libraries for public use, you've most likely been in situations where you have to roll out new updates. Die richtige Vorgehensweise ist hier sehr wichtig, da Sie sicherstellen müssen, dass es einen nahtlosen Übergang von vorhandenem Code auf die neue Version Ihrer Bibliothek gibt.How you go about this process matters a lot as you need to ensure that there's a seamless transition of existing code to the new version of your library. Folgendes Punkte spielen eine Rolle, wenn Sie eine neue Version erstellen:Here are several things to consider when creating a new release:

Semantische VersionskontrolleSemantic Versioning

Semantic versioning (Semantische Versionierung, kurz SemVer) ist eine Namenskonvention, die auf Versionen Ihrer Bibliothek angewendet wird, um bestimmte Meilensteinereignisse zu kennzeichnen.Semantic versioning (SemVer for short) is a naming convention applied to versions of your library to signify specific milestone events. Im Idealfall sollten es die Versionsinformationen Ihrer Bibliothek Entwicklern erleichtern, festzustellen, ob ihre Projekte, die ältere Versionen dieser Bibliothek verwenden, kompatibel sind.Ideally, the version information you give your library should help developers determine the compatibility with their projects that make use of older versions of that same library.

Die einfachste Herangehensweise an SemVer ist das Format MAJOR.MINOR.PATCH mit drei Komponenten, bei dem:The most basic approach to SemVer is the 3 component format MAJOR.MINOR.PATCH, where:

  • MAJOR inkrementiert wird, wenn Sie nicht kompatible API-Änderungen durchführenMAJOR is incremented when you make incompatible API changes
  • MINOR inkrementiert wird, wenn Sie abwärtskompatible Funktionalität hinzufügenMINOR is incremented when you add functionality in a backwards-compatible manner
  • PATCH inkrementiert wird, wenn Sie abwärtskompatible Fehlerkorrekturen durchführenPATCH is incremented when you make backwards-compatible bug fixes

Es besteht auch die Möglichkeit, andere Szenarios wie Vorabversionen usw. anzugeben, wenn Sie die Versionsinformationen auf Ihre .NET-Bibliothek anwenden.There are also ways to specify other scenarios like pre-release versions etc. when applying version information to your .NET library.

AbwärtskompatibilitätBackwards Compatibility

Die Abwärtskompatibilität mit früheren Versionen ist wahrscheinlich eine Ihrer Hauptsorgen, wenn Sie neue Versionen Ihrer Bibliothek veröffentlichen.As you release new versions of your library, backwards compatibility with previous versions will most likely be one of your major concerns. Bei einer neuen Version Ihrer Bibliothek besteht Quellenkompatibilität mit einer früheren Version, wenn Code, der von früheren Versionen abhängt, durch erneutes Kompilieren mit der neuen Version funktionieren kann.A new version of your library is source compatible with a previous version if code that depends on the previous version can, when recompiled, work with the new version. Bei einer neuen Version Ihrer Bibliothek besteht binäre Kompatibilität, wenn eine Anwendung, die von der alten Versionen abhängt, ohne erneutes Kompilieren mit der neuen Version arbeiten kann.A new version of your library is binary compatible if an application that depended on the old version can, without recompilation, work with the new version.

Folgende Punkte sollten Sie beachten, wenn Sie versuchen die Abwärtskompatibilität mit älteren Versionen ihrer Bibliothek aufrechtzuerhalten:Here are some things to consider when trying to maintain backwards compatibility with older versions of your library:

  • Virtuelle Methoden: Wenn Sie eine virtuelle Methode in Ihrer neuen Version in eine nicht-virtuelle Methode umwandeln, bedeutet das, dass die Projekte, die diese Methode außer Kraft setzen, aktualisiert werden müssen.Virtual methods: When you make a virtual method non-virtual in your new version it means that projects that override that method will have to be updated. Es handelt sich um eine schwere grundlegende Änderung, von der stark abgeraten wird.This is a huge breaking change and is strongly discouraged.
  • Methodensignaturen: Wenn Sie beim Aktualisieren des Verhaltens einer Methode ebenfalls deren Signatur ändern müssen, sollten Sie stattdessen eine Überladung erstellen, damit der Code, der diese Methode aufruft, weiterhin funktioniert.Method signatures: When updating a method behaviour requires you to change its signature as well, you should instead create an overload so that code calling into that method will still work. Sie können die alte Methodensignatur immer so ändern, dass sie die neue Methodensignatur aufruft. Dadurch bleibt die Implementierung konsistent.You can always manipulate the old method signature to call into the new method signature so that implementation remains consistent.
  • Obsolete attribute (Attribut „Obsolete“): Sie können dieses Attribut in Ihrem Code verwenden, um Klassen oder Klassenmember anzugeben, die veraltet sind und in zukünftigen Versionen vermutlich gelöscht werden.Obsolete attribute: You can use this attribute in your code to specify classes or class members that are deprecated and likely to be removed in future versions. Dadurch sind Entwickler, die Ihre Bibliothek verwenden, besser auf grundlegende Änderungen vorbereitet.This ensures developers utilizing your library are better prepared for breaking changes.
  • Optionale Methodenargumente: Wenn sie vorher optionale in obligatorische Methodenargumente umwandeln oder ihren Standardwert ändern, muss der gesamte Code, der diese Argumente nicht bereitstellt, aktualisiert werden.Optional Method Arguments: When you make previously optional method arguments compulsory or change their default value then all code that does not supply those arguments will need to be updated.

Hinweis

Obligatorische Argumente in optionale Argumente umzuwandeln, sollte nur geringe Auswirkungen haben, besonders, wenn dadurch das Verhalten der Methode nicht geändert wird.Making compulsory arguments optional should have very little effect especially if it doesn't change the method's behaviour.

Je leichter Sie es Ihren Benutzern machen, auf die neue Version Ihrer Bibliothek zu aktualisieren, desto früher werden sie dieses Upgrade durchführen.The easier you make it for your users to upgrade to the new version of your library, the more likely that they will upgrade sooner.

AnwendungskonfigurationsdateiApplication Configuration File

Als .NET-Entwickler haben Sie sehr wahrscheinlich schon einmal mit der app.config-Datei gearbeitet, die in den meisten Projekttypen enthalten ist.As a .NET developer there's a very high chance you've encountered the app.config file present in most project types. Diese einfache Konfigurationsdatei kann beim Verbessern der Einführung neuer Updates einen großen Unterschied machen.This simple configuration file can go a long way into improving the rollout of new updates. In der Regel sollten Sie Ihre Bibliotheken so anlegen, dass die Informationen, die sich wahrscheinlich häufiger ändern, in der Datei app.config gespeichert werden. Daher muss die Konfigurationsdatei früherer Versionen nur mit der neuen Datei ersetzt werden, wenn solche Informationen aktualisiert werden. Die Bibliothek muss dann nicht mehr neu kompiliert werden.You should generally design your libraries in such a way that information that is likely to change regularly is stored in the app.config file, this way when such information is updated the config file of older versions just needs to be replaced with the new one without the need for recompilation of the library.

Verarbeiten von BibliothekenConsuming Libraries

Als Entwickler, der .NET-Bibliotheken verarbeitet, die von anderen Entwicklern erstellt wurden, sind Sie sich sicher der Tatsache bewusst, dass eine neue Version einer Bibliothek möglicherweise nicht voll kompatibel mit Ihrem Projekt ist, und Sie Ihren Code oft aktualisieren müssen, um auf diese Änderungen zu reagieren.As a developer that consumes .NET libraries built by other developers you're most likely aware that a new version of a library might not be fully compatible with your project and you might often find yourself having to update your code to work with those changes.

Zum Glück gibt es im C# -und .NET-Ökosystem Features und Techniken, mit denen Sie Anwendungen leicht aktualisieren können, damit sie mit neuen Versionen von Bibliotheken funktionieren, mit denen möglicherweise grundlegende Änderungen eingeführt werden.Lucky for you C# and the .NET ecosystem comes with features and techniques that allow us to easily update our app to work with new versions of libraries that might introduce breaking changes.

AssemblybindungsumleitungAssembly Binding Redirection

Sie können die Datei app.config zum Aktualisieren der Version einer von Ihrer Anwendung verwendeten Bibliothek verwenden.You can use the app.config file to update the version of a library your app uses. Durch Hinzufügen einer sogenannten binding redirect (Bindungsumleitung) können Sie die neue Version der Bibliothek verwenden, ohne dass Sie Ihre Anwendung erneut kompilieren müssen.By adding what is called a binding redirect your can use the new library version without having to recompile your app. Im folgenden Beispiel wird gezeigt, wie Sie die Datei app.config Ihrer Anwendung aktualisieren, um die Patchversion 1.0.1 von ReferencedLibrary zu verwenden und nicht die Version 1.0.0, mit der sie ursprünglich kompiliert war.The following example shows how you would update your app's app.config file to use the 1.0.1 patch version of ReferencedLibrary instead of the 1.0.0 version it was originally compiled with.

<dependentAssembly>
    <assemblyIdentity name="ReferencedLibrary" publicKeyToken="32ab4ba45e0a69a1" culture="en-us" />
    <bindingRedirect oldVersion="1.0.0" newVersion="1.0.1" />
</dependentAssembly>

Hinweis

Dieser Ansatz funktioniert nur, wenn die neue Version von ReferencedLibrary binär kompatibel mit Ihrer Anwendung ist.This approach will only work if the new version of ReferencedLibrary is binary compatible with your app. Im Abschnitt Abwärtskompatibilität finden Sie Änderungen, die Sie beachten müssen, wenn Sie die Kompatibilität bestimmen.See the Backwards Compatibility section above for changes to look out for when determining compatibility.

neunew

Sie können den new-Modifizierer verwenden, um geerbte Member einer Basisklasse auszublenden.You use the new modifier to hide inherited members of a base class. Dies ist eine Möglichkeit, wie abgeleitete Klassen auf Updates in Basisklassen reagieren können.This is one way derived classes can respond to updates in base classes.

Betrachten Sie das folgende Beispiel:Take the following example:

public class BaseClass
{
    public void MyMethod()
    {
        Console.WriteLine("A base method");
    }
}

public class DerivedClass : BaseClass
{
    public new void MyMethod()
    {
        Console.WriteLine("A derived method");
    }
}

public static void Main()
{
    BaseClass b = new BaseClass();
    DerivedClass d = new DerivedClass();

    b.MyMethod();
    d.MyMethod();
}

AusgabeOutput

A base method
A derived method

Im obigen Beispiel können Sie sehen, wie DerivedClass die Methode MyMethod ausblendet, die sich in BaseClass befindet.From the example above you can see how DerivedClass hides the MyMethod method present in BaseClass. Das bedeutet, dass Sie einfach den new-Modifizierer auf Ihre abgeleiteten Klassenmember anwenden können, um die Member der Basisklasse auszublenden, wenn von einer Basisklasse in der neuen Version einer Bibliothek Member hinzugefügt werden, die sich bereits in Ihrer abgeleiteten Klasse befinden.This means that when a base class in the new version of a library adds a member that already exists in your derived class, you can simply use the new modifier on your derived class member to hide the base class member.

Wenn kein new-Modifizierer angegeben ist, blendet eine abgeleitete Klasse standardmäßig in Konflikt stehende Member in der Basisklasse aus. Obwohl eine Compilerwarnung generiert wird, kompiliert der Code weiter.When no new modifier is specified, a derived class will by default hide conflicting members in a base class, although a compiler warning will be generated the code will still compile. Das bedeutet, dass die neue Version Ihrer Bibliothek durch das Hinzufügen neuer Member zu einer vorhanden Klasse sowohl quellen- als auch binär kompatibel mit dem Code wird, der von ihr abhängt.This means that simply adding new members to an existing class makes that new version of your library both source and binary compatible with code that depends on it.

overrideoverride

Der override-Modifizierer bedeutet, dass eine abgeleitete Implementierung die Implementierung eines Basisklassenmembers erweitert, anstatt sie auszublenden.The override modifier means a derived implementation extends the implementation of a base class member rather than hides it. Der virtual-Modifizierer muss auf den Basisklassenmember angewendet sein.The base class member needs to have the virtual modifier applied to it.

public class MyBaseClass
{
    public virtual string MethodOne()
    {
        return "Method One";
    }
}

public class MyDerivedClass : MyBaseClass
{
    public override string MethodOne()
    {
        return "Derived Method One";
    }
}

public static void Main()
{
    MyBaseClass b = new MyBaseClass();
    MyDerivedClass d = new MyDerivedClass();

    Console.WriteLine("Base Method One: {0}", b.MethodOne());
    Console.WriteLine("Derived Method One: {0}", d.MethodOne());
}

AusgabeOutput

Base Method One: Method One
Derived Method One: Derived Method One

Der override-Modifizierer wird beim Kompilieren ausgewertet, und der Compiler löst einen Fehler aus, wenn kein virtueller Member gefunden wird, der außer Kraft gesetzt werden kann.The override modifier is evaluated at compile time and the compiler will throw an error if it doesn't find a virtual member to override.

Ihre Kenntnis der besprochenen Techniken und Ihr Wissen, in welchen Situationen diese angewendet werden, kann einen großen Unterschied beim reibungslosen Übergang zwischen den Versionen einer Bibliothek ausmachen.Your knowledge of the discussed techniques as well as your understanding of what situations to use them will go a long way to boost the ease of transition between versions of a library.