In diesem Artikel wird erläutert, wie Sie mithilfe der .NET-CLI Bibliotheken für .NET schreiben. Die CLI bietet effiziente Funktionalität auf niedriger Stufe, die auf allen unterstützten Betriebssystemen funktioniert. Sie können trotzdem noch Bibliotheken mit Visual Studio erstellen. Wenn das Ihre bevorzugte Methode ist, finden Sie weitere Informationen im Handbuch für Visual Studio.
Voraussetzungen
Das .NET SDK muss auf Ihrem Computer installiert sein.
Für die Abschnitte dieses Dokuments, in denen es um .NET Framework-Versionen geht, muss das .NET Framework auf einem Windows-Computer installiert sein.
Wenn Sie ältere .NET Framework-Ziele unterstützen möchten, müssen Sie außerdem Pakete zum Festlegen von Zielversionen oder Entwicklerpakete von der .NET Framework-Downloadseite installieren. Weitere Informationen finden Sie in dieser Tabelle:
.NET Framework-Version
Empfohlene Downloads
4.6.1
Paket zur Festlegung von Zielversionen für .NET Framework 4.6.1
4.6
Paket zur Festlegung von Zielversionen für .NET Framework 4.6
4.5.2
.NET Framework 4.5.2 Entwicklerpaket
4.5.1
.NET Framework 4.5.1 Entwicklerpaket
4.5
Windows Software Development Kit für Windows 8
4,0
Windows SDK für Windows 7 und .NET Framework 4
2.0, 3.0 und 3.5
.NET Framework 3.5 SP1-Runtime (oder Windows 8+-Version)
Verwenden von .NET 5 oder .NET Standard als Ziel
Sie können das Zielframework Ihres Projekts kontrollieren, indem Sie es zu Ihrer Projektdatei hinzufügen ( .csproj oder .fsproj). Informationen, die Sie bei der Entscheidung zwischen .NET 5 oder höher oder .NET Standard als Ziel unterstützen sollen, finden Sie unter .NET 5 oder höher und .NET Standard.
Wenn Sie die .NET Framework-Version 4.0 oder niedriger als Ziel festlegen oder eine API verwenden möchten, die in .NET Framework verfügbar ist, aber nicht in .NET Standard (z. B. System.Drawing), lesen Sie die folgenden Abschnitte. In ihnen erfahren Sie, wie mehrere Ziele festlegt werden.
Vorgehensweise: .NET Framework als Ziel
Hinweis
In diesen Anleitungen wird vorausgesetzt, dass .NET Framework auf Ihrem Computer installiert ist. Informationen zum Installieren von Abhängigkeiten finden Sie unter Erforderliche Komponenten.
Wenn Sie so viele Entwickler und Projekte erreichen möchten wie möglich, verwenden Sie .NET Framework 4.0 als Baselineziel. Um .NET Framework als Ziel festzulegen, müssen Sie zunächst den richtigen Zielframeworkmoniker (Target Framework Moniker, TMF) auswählen, der der .NET Framework-Version entspricht, die Sie unterstützen möchten.
.NET Framework-Version
TFM
.NET Framework 2.0
net20
.NET Framework 3.0
net30
.NET Framework 3.5
net35
.NET Framework 4.0
net40
.NET Framework 4.5
net45
.NET Framework 4.5.1
net451
.NET Framework 4.5.2
net452
.NET Framework 4.6
net46
.NET Framework 4.6.1
net461
.NET Framework 4.6.2
net462
.NET Framework 4.7
net47
.NET Framework 4.8
net48
Sie fügen anschließend TFM in den TargetFramework-Abschnitt Ihrer Projektdatei ein. Hier sehen Sie zum Beispiel, wie Sie eine Bibliothek schreiben, die .NET Framework 4.0 als Ziel festlegt:
Das war’s! Obwohl dieses Beispiel nur für .NET Framework 4 kompiliert wurde, können Sie die Bibliothek für neueren Versionen von .NET Framework verwenden.
Vorgehensweise: Festlegen mehrerer Ziele
Hinweis
In den folgenden Anweisungen wird vorausgesetzt, dass .NET Framework auf Ihrem Computer installiert ist. Im Abschnitt Erforderliche Komponenten finden Sie weitere Informationen darüber, welche Abhängigkeiten Sie installieren müssen, und wo Sie diese herunterladen können.
Sie müssen möglicherweise ältere Versionen des .NET Frameworks als Ziel festlegen, wenn Ihr Projekt sowohl das .NET Framework als auch .NET unterstützt. Wenn Sie neuere APIs und Sprachkonstrukte für die neueren Ziele verwenden möchten, verwenden Sie in diesem Szenario #if-Anweisungen in Ihrem Code. Sie müssen möglicherweise auch unterschiedliche Pakete und Abhängigkeiten für jede Zielplattform hinzufügen, um verschiedene APIs einzuschließen, die für jeden Fall benötigt werden.
Nehmen wir z.B. einmal an, dass Sie eine Bibliothek haben, die Netzwerkvorgänge über HTTP ausführt. Für .NET Standard und die .NET Framework-Versionen 4.5 oder höher können Sie die HttpClient-Klasse aus dem System.Net.Http-Namespace verwenden. Frühere Versionen von .NET Framework verfügen jedoch nicht über die Klasse HttpClient, daher können Sie für diese stattdessen die Klasse WebClient aus dem Namespace System.Net verwenden.
Ihre Projektdatei könnte also Folgendermaßen aussehen:
XML
<ProjectSdk="Microsoft.NET.Sdk"><PropertyGroup><TargetFrameworks>netstandard2.0;net40;net45</TargetFrameworks></PropertyGroup><!-- Need to conditionally bring in references for the .NET Framework 4.0 target --><ItemGroupCondition="'$(TargetFramework)' == 'net40'"><ReferenceInclude="System.Net" /></ItemGroup><!-- Need to conditionally bring in references for the .NET Framework 4.5 target --><ItemGroupCondition="'$(TargetFramework)' == 'net45'"><ReferenceInclude="System.Net.Http" /><ReferenceInclude="System.Threading.Tasks" /></ItemGroup></Project>
Sie sehen hier drei große Veränderungen:
Der TargetFramework-Knoten wurde durch TargetFrameworks ersetzt, und drei TFMs werden darin dargestellt.
Es gibt einen <ItemGroup>-Knoten für das net40-Ziel, der einen .NET Framework-Verweis einbezieht.
Es gibt einen <ItemGroup>-Knoten für das net45-Ziel, der zwei .NET Framework-Verweise einbezieht.
Präprozessorsymbole
Das Buildsystem beachtet die folgenden Präprozessorsymbole, die in #if-Anweisungen verwendet werden:
Zielframeworks
Symbole
Zusätzliche Symbole (verfügbar in SDKs für .NET 5 und höher)
Plattformsymbole (nur verfügbar, wenn Sie einen betriebssystemspezifischen TFM angeben)
ANDROID, BROWSER, IOS, MACCATALYST, MACOS, TVOS, WINDOWS, [OS][version] (z. B. IOS15_1), [OS][version]_OR_GREATER (z. B. IOS15_1_OR_GREATER)
Hinweis
Versionslose Symbole werden unabhängig von der Version definiert, die Sie als Ziel verwenden.
Versionsspezifische Symbole werden nur für die Version definiert, die Sie als Ziel verwenden.
Die <framework>_OR_GREATER-Symbole werden für die Zielversion und alle früheren Versionen definiert. Wenn Sie beispielsweise .NET Framework 2.0 als Ziel festgelegt haben, werden die folgenden Symbole definiert: NET20, NET20_OR_GREATER, NET11_OR_GREATER und NET10_OR_GREATER.
Die NETSTANDARD<x>_<y>_OR_GREATER-Symbole werden nur für .NET Standard-Ziele definiert und nicht für Ziele, die .NET Standard implementieren, z. B. .NET Core und .NET Framework.
Hier sehen sie ein Beispiel, das die bedingte Kompilierung pro Ziel verwendet:
C#
using System;
using System.Text.RegularExpressions;
#if NET40// This only compiles for the .NET Framework 4 targetsusing System.Net;
#else// This compiles for all other targetsusing System.Net.Http;
using System.Threading.Tasks;
#endifnamespaceMultitargetLib
{
publicclassLibrary
{
#if NET40privatereadonly WebClient _client = new WebClient();
privatereadonlyobject _locker = newobject();
#elseprivatereadonly HttpClient _client = new HttpClient();
#endif#if NET40// .NET Framework 4.0 does not have async/awaitpublicstringGetDotNetCount()
{
string url = "https://www.dotnetfoundation.org/";
var uri = new Uri(url);
string result = "";
// Lock here to provide thread-safety.lock(_locker)
{
result = _client.DownloadString(uri);
}
int dotNetCount = Regex.Matches(result, ".NET").Count;
return$"Dotnet Foundation mentions .NET {dotNetCount} times!";
}
#else// .NET Framework 4.5+ can use async/await!publicasync Task<string> GetDotNetCountAsync()
{
string url = "https://www.dotnetfoundation.org/";
// HttpClient is thread-safe, so no need to explicitly lock herevar result = await _client.GetStringAsync(url);
int dotNetCount = Regex.Matches(result, ".NET").Count;
return$"dotnetfoundation.org mentions .NET {dotNetCount} times in its HTML!";
}
#endif
}
}
Wenn Sie diese Projekt mit dotnet build erstellen, bemerken Sie drei Verzeichnisse unter dem bin/-Ordner:
net40/
net45/
netstandard2.0/
Jedes dieser Verzeichnisse enthält die .dll-Dateien für jedes Ziel.
So testen Sie die Bibliotheken unter .NET
Es ist wichtig, über Plattformen hinweg testen zu können. Sie können entweder xUnit oder MSTest standardmäßig verwenden. Beide sind bestens für Komponententests für Ihre Bibliothek unter .NET geeignet. Wie Sie Ihre Lösung mit Testprojekten einrichten, hängt von der Struktur Ihrer Lösung ab. Im folgenden Beispiel wird davon ausgegangen, dass Test- und Quellverzeichnisse im gleichen Verzeichnis auf oberster Ebene vorhanden sind.
Dadurch werden Projekte erstellt, die zusammen in einer Projektmappe verknüpft werden. Ihr Verzeichnis für SolutionWithSrcAndTest sollte in etwa so aussehen:
Navigieren Sie zum Verzeichnis des Testprojekts, und fügen Sie einen Verweis zu MyProject.Test von MyProject hinzu.
.NET CLI
cd MyProject.Test
dotnetadd reference ../MyProject/MyProject.csproj
So stellen Sie Pakete wieder her und erstellen Projekte:
.NET CLI
dotnetrestoredotnetbuild
Überprüfen Sie, ob xUnit durch Ausführung des dotnet test-Befehls ausgeführt wird. Wenn Sie MSTests verwenden möchten, dann muss stattdessen das MSTest-Konsolenausführungsprogramm ausgeführt werden.
Das war’s! Jetzt können Sie Ihre Bibliothek mithilfe der Befehlszeilentools plattformübergreifend testen. Nachdem jetzt alles eingerichtet ist, ist das weitere Testen Ihrer Bibliothek sehr einfach:
Nehmen Sie Änderungen an Ihrer Bibliothek vor.
Führen Sie mit dem Befehl dotnet test in Ihrem Testverzeichnis Tests über die Befehlszeile aus.
Der Code wird automatisch neu erstellt, wenn Sie den Befehl dotnet test aufrufen.
So verwenden Sie mehrere Projekte
Eine häufige Anforderung an größere Bibliotheken ist es, Funktionalität in verschiedenen Projekten zu bieten.
Stellen Sie sich vor, Sie möchten eine Bibliothek erstellen, die in idiomatischem C# und F# genutzt werden kann. Das würde bedeuten, dass Benutzer Ihrer Bibliotheken diese auf eine Art nutzen, die natürlich für C# und F# ist. In C# z.B. könnten Sie die Bibliothek wie folgt nutzen:
C#
using AwesomeLibrary.CSharp;
public Task DoThings(Data data)
{
var convertResult = await AwesomeLibrary.ConvertAsync(data);
var result = AwesomeLibrary.Process(convertResult);
// do something with result
}
In F# wird wie folgt formuliert:
F#
open AwesomeLibrary.FSharp
let doWork data = async {
let! result = AwesomeLibrary.AsyncConvert data // Uses an F# async function rather than C# async method// do something with result
}
Solche Nutzungsszenarios bedeuten, dass die APIs, auf die zugegriffen wird, eine andere Struktur für C# und F# haben müssen. Eine gängige Methode, dies zu erreichen ist, die gesamte Logik einer Bibliothek in ein Kernprojekt zu zerlegen, in dem C# und F# Projekte die API-Schichten definieren, die das Kernprojekt aufrufen. Im übrigen Abschnitt werden die folgenden Namen verwendet:
AwesomeLibrary.Core – Ein Kernprojekt, das die gesamte Logik für die Bibliothek enthält
AwesomeLibrary.CSharp – Ein Projekt mit öffentlichen APIs, die für den Gebrauch in C# vorgesehen sind
AwesomeLibrary.FSharp – Ein Projekt mit öffentlichen APIs, die für den Gebrauch in F# vorgesehen sind
Sie können die folgenden Befehle in Ihrem Terminal ausführen, um die gleiche Struktur wie dieses Handbuch zu erstellen:
.NET CLI
mkdir AwesomeLibrary && cd AwesomeLibrary
dotnetnewsln
mkdir AwesomeLibrary.Core && cd AwesomeLibrary.Core && dotnetnew classlib
cd ..
mkdir AwesomeLibrary.CSharp && cd AwesomeLibrary.CSharp && dotnetnew classlib
cd ..
mkdir AwesomeLibrary.FSharp && cd AwesomeLibrary.FSharp && dotnetnew classlib -lang"F#"cd ..
dotnetslnadd AwesomeLibrary.Core/AwesomeLibrary.Core.csproj
dotnetslnadd AwesomeLibrary.CSharp/AwesomeLibrary.CSharp.csproj
dotnetslnadd AwesomeLibrary.FSharp/AwesomeLibrary.FSharp.fsproj
Dadurch werden die drei oben genannten Projekte und eine Projektmappendatei hinzugefügt, die sie verknüpft. Durch das Erstellen der Projektmappendatei und das Verknüpfen der Projekte können Sie Projekte auf oberster Ebene wiederherstellen und erstellen.
Projekt-zu-Projekt-Verweise
Die beste Möglichkeit, auf ein Projekt zu verweisen, ist die Verwendung der .NET-CLI, um einen Projektverweis hinzuzufügen. Sie können den folgenden Befehl von den Projektverzeichnissen AwesomeLibrary.CSharp und AwesomeLibrary.FSharp ausführen:
Die Projektdateien für AwesomeLibrary.CSharp und AwesomeLibrary.FSharp verweisen nun auf AwesomeLibrary.Core als ProjectReference-Ziel. Sie können dies überprüfen, indem Sie die Projektdateien prüfen und Folgendes darin sehen:
Sie können jeder Projektdatei diesen Abschnitt manuell hinzufügen, wenn Sie nicht die .NET-CLI verwenden möchten.
Strukturieren einer Projektmappe
Ein weiterer wichtiger Aspekt bei mehreren Projekten in einer Projektmappe ist es, eine gute allgemeine Projektstruktur einzurichten. Sie können den Code beliebig organisieren, solange Sie jedes Projekt mit Ihrer Projektmappendatei mit dotnet sln add verknüpfen. Dadurch können Sie dotnet restore und dotnet build auf Projektmappenebene ausführen.
Zusammenarbeit auf GitHub
Die Quelle für diesen Inhalt finden Sie auf GitHub, wo Sie auch Issues und Pull Requests erstellen und überprüfen können. Weitere Informationen finden Sie in unserem Leitfaden für Mitwirkende.
Feedback zu .NET
.NET ist ein Open Source-Projekt. Wählen Sie einen Link aus, um Feedback zu geben:
Hier erstellen Sie ein .NET-Projekt und erfahren, wie Sie in Ihrem Projekt Pakete hinzufügen und Paketabhängigkeiten verwalten. Verwenden Sie die .NET Core-CLI und die NuGet-Registrierung, um Ihren C#-Anwendungen über Visual Studio Code Bibliotheken und Tools hinzuzufügen.