IConfiguration vs IOptions NET
Synchronous and Asynchronous in .NET Core
Model Binding and Validation in ASP.NET Core
ControllerBase vs Controller in ASP.NET Core
ConfigureServices and Configure methods
IHostedService interface in .NET Core
ASP.NET Core request processing
| Service-Discovery-and-health-Check | Eventual Consistency | |
Saga Pattern in .NET Core |
The Saga Pattern is used in microservices to manage distributed transactions. Instead of a single ACID transaction across services, it breaks the workflow into smaller steps (local transactions). If one step fails, compensating transactions roll back the previous steps.
Imagine an Order Service that coordinates with Payment Service and Inventory Service.
// Order Saga Orchestrator (simplified)
public class OrderSaga
{
public async Task ExecuteAsync()
{
try
{
await ReserveInventory();
await ProcessPayment();
await ConfirmOrder();
}
catch (Exception)
{
await Compensate();
}
}
private Task ReserveInventory() => Task.Run(() => Console.WriteLine("Inventory Reserved"));
private Task ProcessPayment() => Task.Run(() => Console.WriteLine("Payment Processed"));
private Task ConfirmOrder() => Task.Run(() => Console.WriteLine("Order Confirmed"));
// Compensation logic
private Task Compensate() => Task.Run(() => Console.WriteLine("Rollback: Cancel Payment & Release Inventory"));
}
The Saga Pattern is a powerful way to handle distributed transactions in microservices. In .NET Core, it can be implemented using orchestration or event-driven choreography. While it adds complexity, it ensures resilience and consistency in large-scale systems.
MassTransit is a popular .NET library for message-based distributed applications. It provides built-in support for the Saga Pattern, which helps manage long-running workflows across multiple services using state machines and message queues.
Consider an e-commerce flow: Order Service β Payment Service β Shipping Service. If payment fails, the saga compensates by canceling the order.
using MassTransit;
using System;
// Define Saga State
public class OrderState : SagaStateMachineInstance
{
public Guid CorrelationId { get; set; }
public string CurrentState { get; set; }
public string OrderId { get; set; }
}
// Define Events
public class OrderSubmitted
{
public string OrderId { get; set; }
}
public class PaymentCompleted
{
public string OrderId { get; set; }
}
public class PaymentFailed
{
public string OrderId { get; set; }
}
// Define State Machine
public class OrderStateMachine : MassTransitStateMachine<OrderState>
{
public State Submitted { get; private set; }
public State Completed { get; private set; }
public State Failed { get; private set; }
public Event<OrderSubmitted> OrderSubmittedEvent { get; private set; }
public Event<PaymentCompleted> PaymentCompletedEvent { get; private set; }
public Event<PaymentFailed> PaymentFailedEvent { get; private set; }
public OrderStateMachine()
{
InstanceState(x => x.CurrentState);
Event(() => OrderSubmittedEvent, x => x.CorrelateById(m => m.Message.OrderId));
Event(() => PaymentCompletedEvent, x => x.CorrelateById(m => m.Message.OrderId));
Event(() => PaymentFailedEvent, x => x.CorrelateById(m => m.Message.OrderId));
Initially(
When(OrderSubmittedEvent)
.Then(context => context.Instance.OrderId = context.Data.OrderId)
.TransitionTo(Submitted));
During(Submitted,
When(PaymentCompletedEvent)
.TransitionTo(Completed),
When(PaymentFailedEvent)
.TransitionTo(Failed)
.Then(context => Console.WriteLine("Compensating: Cancel Order")));
}
}
MassTransit makes implementing the Saga Pattern in .NET Core much easier by providing state machines, persistence, and message-driven orchestration. Itβs ideal for distributed systems where workflows span multiple services and need resilience.
| Service-Discovery-and-health-Check | Eventual Consistency | |