The Legacy Migrator’s Diary: Week 1
The Single Responsibility Principle Meets Operational Excellence
The Legacy Migrator’s Diary: Week 1
The Single Responsibility Principle Meets Operational Excellence
The Journal Entry
It’s Monday morning, Week 1 of our massive e-commerce migration to AWS. Our target is the core OrderProcessingManager class. In our legacy on-premises monolith, this single class is a 4,000-line monstrosity. When a customer clicks "Place Order," this class handles database writes, authorizes credit cards, updates inventory levels, sends confirmation emails, and writes local text logs.
Last Black Friday, our email server lagged under heavy load. Because the code was tightly bound, the entire OrderProcessingManager hung waiting for an SMTP timeout, which backed up our database connections and crashed the entire checkout line. That is a massive failure under the AWS Well-Architected Operational Excellence Pillar, which demands that systems are designed to evolve, track health, and isolate failures seamlessly.
Our mission this week: Apply the Single Responsibility Principle (SRP). A class should have one, and only one, reason to change. By breaking this monolith apart in C#, we can naturally map it to decoupled AWS compute layers!
The Refactoring Ledger
The Before: The On-Premises Spaghetti Monolith
Here is a snapshot of the bloated C# class that brought down our business. It tries to orchestrate everything synchronously:
public class OrderProcessingManager
{
public void ProcessOrder(Order order)
{
// 1. Core Domain Logic
SaveOrderToDatabase(order);
// 2. Payment Integration
var paymentClient = new HttpClient();
paymentClient.PostAsync("https://api.paymentgateway.com", new StringContent(order.Amount.ToString()));
// 3. Notification Logic (The Ticking Time Bomb)
using (var smtpClient = new SmtpClient("smtp.internal.local"))
{
smtpClient.Send(new MailMessage("sales@shop.com", order.CustomerEmail, "Order Confirmed", "Thank you!"));
}
// 4. Observability Logic
File.WriteAllText(@"C:\Logs\orders.txt", $"Processed order {order.Id} at {DateTime.UtcNow}");
}
private void SaveOrderToDatabase(Order order) { /* SQL Logic */ }
}
Why this fails Operational Excellence: We can’t update our email templates without redeploying the core payment and database logic. If the SMTP server goes down, the entire transaction fails.
The After: SRP Code & The Hybrid Cloud Architecture
We refactored the code by separating concerns into dedicated, lightweight classes. This code clarity gave us the freedom to pick the absolute best AWS compute environment for each specific workload.
1. Core API Control Layer (Deployed on ECS Fargate)
We kept our core checkout workflow inside a containerized .NET Web API running on ECS Fargate. This gives us complete control over our language runtime version, avoids Lambda cold starts during flash sales, and simplifies our deployment to a clean Docker image.
public class CheckoutService : ICheckoutService
{
private readonly IOrderRepository _repository;
private readonly IPaymentProcessor _paymentProcessor;
private readonly IMessagePublisher _messagePublisher;
public CheckoutService(IOrderRepository repository, IPaymentProcessor paymentProcessor, IMessagePublisher messagePublisher)
{
_repository = repository;
_paymentProcessor = paymentProcessor;
_messagePublisher = messagePublisher; // Interfaces make cloud-swapping easy!
}
public async Task PlaceOrderAsync(Order order)
{
// Handle only the bare minimum required to secure the transaction
await _repository.SaveAsync(order);
await _paymentProcessor.AuthorizeAsync(order);
// Instantly hand off downstream work asynchronously to AWS SQS
await _messagePublisher.PublishOrderCreatedEventAsync(order);
}
}
2. Event-Driven Notification Layer (Deployed on AWS Lambda)
Instead of keeping the heavy email logic inside our container, we offloaded it to an AWS Lambda function triggered directly by an Amazon SQS queue. Lambda is perfect here: it scales to infinity instantly when thousands of order messages drop into the queue, and if the email system fails, SQS safely retries the message without interrupting the shopper’s checkout experience!
public class OrderNotificationLambdaHandler
{
private readonly IEmailSender _emailSender;
public OrderNotificationLambdaHandler(IEmailSender emailSender)
{
_emailSender = emailSender;
}
// Triggered automatically by AWS SQS when an order event arrives
public async Task HandleSQSEventAsync(SQSEvent sqsEvent)
{
foreach (var record in sqsEvent.Records)
{
var order = JsonSerializer.Deserialize<Order>(record.Body);
await _emailSender.SendConfirmationEmailAsync(order.CustomerEmail, order.Id);
}
}
}
The Operational Excellence Win
By applying SRP in our C# code, our architectural layout transformed. Our core container on ECS Fargate stays lean, fast, and highly available. Meanwhile, our auxiliary workflows (notifications, analytics) are isolated inside serverless Lambdas. We can now deploy, monitor, and scale our email system independently without ever risking a single credit card transaction.
메타데이터
- post_id
- cc4e40294b78
- slug
- the-legacy-migrators-diary-week-1-cc4e40294b78
- url
- https://medium.com/@naved-shaikh/the-legacy-migrators-diary-week-1-cc4e40294b78
- canonical_url
- https://medium.com/@naved-shaikh/the-legacy-migrators-diary-week-1-cc4e40294b78
- author_url
- https://medium.com/@naved-shaikh
- status
- ok
- fetched_at
- 2026-07-13 06:23:13