Einführung in Mikroservices mit C#
\nDie Mikroservice-Architektur ist zum De-facto-Standard für die Entwicklung komplexer, skalierbarer und ausfallsicherer Anwendungen geworden. Im Gegensatz zum Monolithen, bei dem der gesamte Code in einem einzigen Prozess vereint ist, unterteilen Mikroservices das System in kleine, unabhängig bereitstellbare Dienste. Die .NET-Plattform (C#) bietet alle notwendigen Werkzeuge zur Erstellung professioneller Mikroservices: von ASP.NET Core für Web-APIs bis hin zu Bibliotheken für die Arbeit mit Warteschlangen, Containerisierung und Orchestrierung.
\nIn diesem Artikel betrachten wir den gesamten Weg von der Architekturplanung bis zur praktischen Implementierung eines Mikroservices in C# mit Codebeispielen.
\n\n1. Grundlagen der Mikroservice-Architektur
\nPrinzipien und Antipatterns
\nBevor wir Code schreiben, ist es wichtig, die Schlüsselprinzipien zu verstehen:
\n- \n
- Einzelverantwortung (SRP): Jeder Service ist für eine einzige Geschäftsfunktion verantwortlich (z. B. Bestellservice, Zahlungsservice). \n
- Lockere Kopplung: Services kommunizieren über das Netzwerk (HTTP, gRPC, Warteschlangen) und kennen die interne Struktur der anderen nicht. \n
- Unabhängige Bereitstellung: Sie können einen Service aktualisieren, ohne andere zu stoppen. \n
- Daten-Dezentralisierung: Jeder Service besitzt seine eigene Datenbank (Database per Service). \n
Antipatterns, die vermieden werden sollten: Zu kleine Services (Nanoservices), gemeinsame Datenbank, synchrone Aufrufketten (Chattiness).
\n\nKommunikation zwischen Services
\nFür die Interaktion von Mikroservices in C# werden verwendet:
\n- \n
- Synchron: REST API (HTTP/JSON) oder gRPC (binäres Protokoll, schneller). \n
- Asynchron: Nachrichtenwarteschlangen (RabbitMQ, Azure Service Bus, Kafka) – bevorzugte Methode für lockere Kopplung. \n
2. Praktische Implementierung eines Mikroservices in C#
\nBeispiel: Bestellverwaltungsservice
\nErstellen wir einen einfachen Mikroservice mit ASP.NET Core 8. Wir verwenden Clean Architecture zur Schichtentrennung.
\n\nSchritt 1: Projekt und Struktur
\ndotnet new webapi -n OrderService\ncd OrderService\nOrdner erstellen: Controllers, Models, Services, Data.
Schritt 2: Datenmodell
\n// Models/Order.cs\npublic class Order\n{\n public int Id { get; set; }\n public string CustomerName { get; set; }\n public decimal TotalAmount { get; set; }\n public DateTime CreatedAt { get; set; }\n}\n\nSchritt 3: Datenbankkontext (Entity Framework Core)
\n// Data/OrderDbContext.cs\npublic class OrderDbContext : DbContext\n{\n public OrderDbContext(DbContextOptions<OrderDbContext> options) : base(options) { }\n public DbSet<Order> Orders { get; set; }\n}\n\nSchritt 4: Serviceschicht
\n// Services/IOrderService.cs\npublic interface IOrderService\n{\n Task<Order> CreateOrderAsync(Order order);\n Task<List<Order>> GetAllOrdersAsync();\n}\n\n// Services/OrderService.cs\npublic class OrderService : IOrderService\n{\n private readonly OrderDbContext _context;\n public OrderService(OrderDbContext context)\n {\n _context = context;\n }\n\n public async Task<Order> CreateOrderAsync(Order order)\n {\n _context.Orders.Add(order);\n await _context.SaveChangesAsync();\n return order;\n }\n\n public async Task<List<Order>> GetAllOrdersAsync()\n {\n return await _context.Orders.ToListAsync();\n }\n}\n\nSchritt 5: Controller
\n// Controllers/OrdersController.cs\n[ApiController]\n[Route("api/[controller]")]\npublic class OrdersController : ControllerBase\n{\n private readonly IOrderService _orderService;\n public OrdersController(IOrderService orderService)\n {\n _orderService = orderService;\n }\n\