Das dotnet-Werkzeug
| Befehl | Zweck |
|---|---|
dotnet new console -o Name | Konsolenprogramm anlegen |
dotnet new classlib, webapi, xunit | Bibliothek, Web-API, Tests |
dotnet new sln + dotnet sln add ... | Projektmappe |
dotnet run | übersetzen und starten |
dotnet build | übersetzen |
dotnet test | Tests ausführen |
dotnet publish -c Release | Auslieferungsfähige Dateien |
dotnet add package Name | NuGet-Paket hinzufügen |
dotnet format, dotnet watch run | formatieren, Neustart bei Änderung |
Projektdatei
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>
</Project>ImplicitUsings fügt häufige using-Zeilen automatisch ein, Nullable aktiviert die Null-Analyse.
Namensräume
namespace Kurs.Modelle; // dateiweiter Namensraum
public class Artikel
{
public required string Name { get; init; }
public decimal Preis { get; init; }
}using Kurs.Modelle;
var a = new Artikel { Name = "Stift", Preis = 1.5m };Eine Datei hat meist eine Klasse und heißt wie die Klasse. Der Namensraum folgt der Ordnerstruktur.
Tests mit xUnit
dotnet new xunit -o Kurs.Tests
dotnet add Kurs.Tests reference Kurs
dotnet testusing Xunit;
public class RechnerTests
{
[Fact]
public void Addiere_ZweiZahlen_LiefertSumme()
{
Assert.Equal(5, Rechner.Addiere(2, 3));
}
[Theory]
[InlineData(2, 3, 5)]
[InlineData(0, 0, 0)]
[InlineData(-1, 1, 0)]
public void Addiere_VieleFaelle(int a, int b, int erwartet)
{
Assert.Equal(erwartet, Rechner.Addiere(a, b));
}
[Fact]
public void Teile_DurchNull_WirftFehler()
{
Assert.Throws<DivideByZeroException>(() => Rechner.Teile(1, 0));
}
}Ein Test hat drei Teile (Arrange – Act – Assert): vorbereiten, ausführen, prüfen. Alternativen zu xUnit: NUnit und MSTest. Zum Ersetzen von Abhängigkeiten gibt es Moq oder NSubstitute.
Das Prinzip ohne Bibliothek:
int fehler = 0;
void Pruefe(string name, object erwartet, object ist)
{
bool ok = erwartet.Equals(ist);
if (!ok) fehler++;
Console.WriteLine($"{(ok ? "OK " : "FEHLER")} {name}");
}
Pruefe("addiere", 5, Rechner.Addiere(2, 3));
Pruefe("addiere negativ", -1, Rechner.Addiere(2, -3));
Pruefe("palindrom", true, Rechner.IstPalindrom("Anna"));
Pruefe("kein palindrom", false, Rechner.IstPalindrom("Hallo"));
Console.WriteLine($"{fehler} Fehler");
static class Rechner
{
public static int Addiere(int a, int b) => a + b;
public static bool IstPalindrom(string s)
{
var t = new string(s.ToLower().Where(char.IsLetterOrDigit).ToArray());
return t.SequenceEqual(t.Reverse());
}
}Ausgabe
OK addiere OK addiere negativ OK palindrom OK kein palindrom 0 Fehler
Eine Web-API in wenigen Zeilen
ASP.NET Core (Minimal API) zeigt die Stärke von C# im Webbereich:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSingleton<IArtikelDienst, ArtikelDienst>();
var app = builder.Build();
app.MapGet("/artikel", (IArtikelDienst d) => d.Alle());
app.MapGet("/artikel/{id:int}", (int id, IArtikelDienst d) =>
d.Finde(id) is { } a ? Results.Ok(a) : Results.NotFound());
app.MapPost("/artikel", (Artikel a, IArtikelDienst d) => Results.Created($"/artikel/{d.Neu(a).Id}", a));
app.Run();Start mit dotnet run. Die Antworten werden automatisch als JSON geliefert.
Datenbanken
| Werkzeug | Zweck |
|---|---|
| Entity Framework Core | ORM: Klassen ↔ Tabellen, Migrationen, LINQ-Abfragen |
| Dapper | schlanker SQL-Helfer |
| ADO.NET | grundlegende Datenbankzugriffe |
public class ShopContext : DbContext
{
public DbSet<Artikel> Artikel => Set<Artikel>();
protected override void OnConfiguring(DbContextOptionsBuilder o) => o.UseSqlite("Data Source=shop.db");
}
using var db = new ShopContext();
var teuer = db.Artikel.Where(a => a.Preis > 10).OrderBy(a => a.Name).ToList(); // wird zu SQLLogging und Konfiguration
Nutze ILogger<T> (Microsoft.Extensions.Logging) statt Console.WriteLine, appsettings.json und Umgebungsvariablen für Einstellungen, und User Secrets bzw. Umgebungsvariablen für Geheimnisse (nie im Code).
Merke
dotnet new/run/build/test/publish/add packagesind die Standardbefehle- Die
.csprojenthält Framework, Nullable und NuGet-Pakete - xUnit:
[Fact],[Theory],Assert.Equal; Arrange–Act–Assert - ASP.NET Core Minimal APIs und Entity Framework Core decken Web und Datenbank ab
- Konfiguration und Geheimnisse gehören nicht in den Quellcode
Aufgabe
Lege mit dotnet new eine Lösung mit einer Bibliothek und einem xUnit-Testprojekt an und schreibe vier Tests.