Mikroservices in C# (.NET): Von der Theorie zur Praxis
In der modernen Softwareentwicklung ist die Microservice-Architektur zum Standard für den Aufbau skalierbarer und ausfallsicherer Systeme geworden. Die .NET-Plattform bietet alle notwendigen Werkzeuge zur Erstellung zuverlässiger Microservices in C#. In diesem Artikel betrachten wir die wichtigsten Architekturprinzipien, praktische Codebeispiele und Best Practices, die Ihnen helfen, mit dem Bau von Microservices in C# zu beginnen.
1. Grundlagen der Microservice-Architektur in .NET
Microservices sind ein Entwicklungsansatz, bei dem eine Anwendung in kleine, unabhängige Dienste aufgeteilt wird, die jeweils für eine eigene Geschäftsfunktion verantwortlich sind. Im .NET-Ökosystem wird dafür ASP.NET Core verwendet – ein leichtgewichtiges und plattformübergreifendes Framework.
Wichtige Prinzipien von Microservices in C#:
- Unabhängige Bereitstellung – jeder Dienst kann aktualisiert werden, ohne andere zu stoppen.
- Lockere Kopplung – Dienste kommunizieren über API (REST, gRPC) oder Message Queues.
- Eigene Datenbank – jeder Microservice besitzt seine eigenen Daten (Database per Service).
- Ausfallsicherheit – der Ausfall eines Dienstes sollte nicht das gesamte System blockieren.
Beginnen wir mit der Erstellung eines einfachen Microservices in C#. Wir verwenden die ASP.NET Core Web API-Vorlage.
// Erstellen eines neuen Microservice-Projektsdotnet new webapi -n OrderServicecd OrderService
// Beispiel eines einfachen Controllers[ApiController][Route("api/[controller]")]public class OrdersController : ControllerBase{ private readonly IOrderRepository _repository;
public OrdersController(IOrderRepository repository) { _repository = repository; }
[HttpGet("{id}")] public async Task<IActionResult> GetOrder(int id) { var order = await _repository.GetByIdAsync(id); if (order == null) return NotFound(); return Ok(order); }
[HttpPost] public async Task<IActionResult> CreateOrder(OrderDto orderDto) { var order = new Order(orderDto.CustomerId, orderDto.TotalAmount); await _repository.AddAsync(order); return CreatedAtAction(nameof(GetOrder), new { id = order.Id }, order); }}2. Dienstübergreifende Kommunikation: REST, gRPC und Queues
Microservices müssen miteinander kommunizieren. In .NET stehen drei Hauptansätze zur Verfügung:
REST API (HTTP)
Der einfachste und verbreitetste Weg. Verwenden Sie HttpClient mit einer Factory für die richtige Verbindungsverwaltung.
// Beispiel für den Aufruf eines anderen Microservice über HttpClientpublic class InventoryServiceClient{ private readonly HttpClient _httpClient;
public InventoryServiceClient(HttpClient httpClient) { _httpClient = httpClient; }
public async Task<bool> CheckStockAsync(int productId, int quantity) { var response = await _httpClient.GetAsync( $"/api/inventory/check?productId={productId}&quantity={quantity}"); return response.IsSuccessStatusCode; }}
// Registrierung in Program.csbuilder.Services.AddHttpClient<InventoryServiceClient>(client =>{ client.BaseAddress = new Uri("http://inventory-service:5001");});gRPC
Für hochperformante synchrone Kommunikation verwenden Sie gRPC. Es basiert auf HTTP/2 und Protocol Buffers.
// Definition des Dienstes in der .proto-Dateisyntax = "proto3";
service OrderProcessor { rpc ProcessOrder (OrderRequest) returns (OrderResponse);}
message OrderRequest { int32 order_id = 1; string customer_email = 2;}
message OrderResponse { bool success = 1; string message = 2;}
// Serverseite in C#public class OrderProcessorService : OrderProcessor.OrderProcessorB