CQRS und Event Sourcing in C#: Architektur für komplexe Systeme

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Wenn gewöhnliches CRUD nicht mehr funktioniert: Einführung in CQRS und Event Sourcing

\n\n

Stellen Sie sich vor, Sie schreiben ein System für eine Bank. Jede Sekunde überprüfen Hunderte von Benutzern ihr Guthaben, überweisen Geld, eröffnen Einlagen. Ihre Anwendung in C# läuft auf einem standardmäßigen Entity Framework mit typischen CRUD-Operationen. Und plötzlich – die Datenbank stürzt ab. Warum? Weil ein schwerer Bericht eine Tabelle blockiert hat, während eine Transaktion geschrieben wurde. Kommt Ihnen bekannt vor?

\n\n

Entwickler komplexer Systeme in C# stoßen früher oder später an die Grenzen der klassischen Architektur. Zwei leistungsstarke Muster kommen zur Hilfe: CQRS (Command Query Responsibility Segregation) und Event Sourcing. Lassen Sie uns sie in der Praxis durchgehen – mit lebendigen Beispielen, nicht mit trockener Theorie.

\n\n

Was ist CQRS und warum ist es nicht nur "Trennung"?

\n\n

CQRS geht nicht darum, Methoden in verschiedene Ordner zu legen. Es ist eine Philosophie: Befehle (ändern den Zustand) und Abfragen (lesen den Zustand) sollten getrennt leben. Im klassischen CRUD haben Sie ein Datenmodell sowohl zum Lesen als auch zum Schreiben. In CQRS gibt es mindestens zwei.

\n\n

Das Problem des klassischen Ansatzes

\n

Angenommen, Sie haben ein UserRepository mit einer Methode GetUserById. Wenn Sie einen Benutzer zur Anzeige auf dem Bildschirm lesen, benötigen Sie 3 Felder. Wenn Sie ihn aktualisieren, benötigen Sie 10 Felder und Prüfungen. Infolgedessen wird ein Modell zu einem Monster mit null-Feldern und verwirrenden Mappern.

\n\n

In CQRS trennen Sie die Verantwortlichkeiten:

\n
    \n
  • Command – führt eine Aktion aus (z. B. CreateOrderCommand)
  • \n
  • Query – gibt Daten zurück (z. B. GetOrderQuery)
  • \n
  • Read Model – flaches DTO, zugeschnitten auf einen bestimmten Bildschirm
  • \n
  • Write Model – reichhaltiges Domänenmodell mit Geschäftslogik
  • \n
\n\n

CQRS in C# mit MediatR schreiben

\n

Der beliebteste Weg, CQRS in C# zu implementieren, ist die Verwendung der Bibliothek MediatR. Sie implementiert das Mediator-Muster und passt perfekt zum Konzept von Befehlen und Abfragen.

\n\n

Schritt 1: Definieren eines Befehls

\n
public record CreateOrderCommand(\n    Guid CustomerId,\n    List<OrderItemDto> Items,\n    string ShippingAddress\n) : IRequest<Guid>;  // Gibt die ID der erstellten Bestellung zurück
\n\n

Schritt 2: Befehlshandler

\n
public class CreateOrderCommandHandler : IRequestHandler<CreateOrderCommand, Guid>\n{\n    private readonly IOrderRepository _orderRepository;\n    private readonly IUnitOfWork _unitOfWork;\n\n    public CreateOrderCommandHandler(IOrderRepository orderRepository, IUnitOfWork unitOfWork)\n    {\n        _orderRepository = orderRepository;\n        _unitOfWork = unitOfWork;\n    }\n\n    public async Task<Guid> Handle(CreateOrderCommand request, CancellationToken cancellationToken)\n    {\n        // Geschäftslogik: Prüfung, Validierung, Erstellung\n        var order = new Order(request.CustomerId, request.ShippingAddress);\n        \n        foreach (var item in request.Items)\n        {\n            order.AddItem(item.ProductId, item.Quantity, item.Price);\n        }\n\n        await _orderRepository.AddAsync(order);\n        await _unitOfWork.SaveChangesAsync(cancellationToken);\n        \n        return order.Id;\n    }\n}
\n\n

Schritt 3: Definieren einer Abfrage

\n
public record GetOrderSummaryQuery(Guid OrderId) : IRequest<OrderSummaryDto>;
\n\n

Schritt 4: Abfragehandler (liest aus einer separaten Datenbank!)

\n
public class GetOrderSummaryQueryHandler : IRequestHandler<GetOrderSummaryQuery, OrderSummaryDto>\n{\n    private readonly IReadDbContext _readDbContext; // Separater Kontext zum Lesen\n\n    public GetOrderSummaryQueryHandler(IReadDbContext read                

Blogs

Buchempfehlungen