Introduction

Microservices architecture has become the preferred approach for building scalable, maintainable, and cloud-native applications. However, most real-world systems do not start as microservices. They start as monolithic applications, often built years ago, running critical business logic.

A common misconception is that adopting microservices requires a complete rewrite. In reality, rewriting a monolith from scratch is risky, expensive, and rarely successful.

This article explains how to build microservices via an existing monolith in .NET Core, using a safe and proven migration strategy known as the Strangler Fig Pattern.

What Is a Monolithic Application?

A monolith is an application where:

Challenges of a Monolith

Despite these challenges, monoliths are not “bad”. They are often stable and business-critical, which is why careful evolution is needed.

Why Not Rewrite Everything as Microservices?

A full rewrite introduces:

Instead of replacing the monolith, a gradual migration is the safest approach.

What Does “Microservices via Monolith” Mean?

“Microservices via Monolith” means:

This approach allows teams to:

The Strangler Fig Pattern

The Strangler Fig Pattern is a migration strategy where:

  1. New features are built as microservices

  2. Existing functionality is slowly moved out

  3. The monolith eventually becomes obsolete

Named after the strangler fig tree, which grows around an existing tree until it replaces it.

High-Level Architecture

Client
  |
API Gateway / Reverse Proxy
  |
----------------------------
|          |               |
Monolith  Microservice A  Microservice B

Step-by-Step Migration in .NET Core

Step 1: Modularize the Monolith

Before extracting services, clean up the monolith:

Tip: If your monolith is already in ASP.NET Core, you are halfway there.

Step 2: Identify a Candidate Microservice

Good candidates:

Examples:

Step 3: Create a New ASP.NET Core Microservice

Create a new project:

dotnet new webapi -n NotificationService

This service should:

Step 4: Route Traffic Using an API Gateway

Use tools like:

Example with YARP:

This makes the migration invisible to clients.

Step 5: Data Management Strategy

Avoid sharing databases.

Common approaches:

Never let microservices directly access the monolith database.

Step 6: Communication Between Monolith and Microservices

Preferred methods:

Example:

Example: Extracting Notification Service

Before (Monolith)

public class OrderService
{
    public void CreateOrder()
    {
        // Order logic
        SendEmail();
    }
}

After (Microservice)

// Monolith
PublishEvent(new OrderCreatedEvent());

// Notification Microservice
public class OrderCreatedHandler
{
    public Task Handle(OrderCreatedEvent evt)
    {
        SendEmail();
    }
}

Result:

Benefits of Microservices via Monolith

Common Mistakes to Avoid

Tools Commonly Used in .NET Core Microservices

When Should You Stop?

The migration ends when:

At this point, the monolith can be safely decommissioned.

Conclusion

Migrating from a monolith to microservices does not require a risky rewrite. By using the Microservices via Monolith approach with .NET Core and the Strangler Fig Pattern, teams can modernize their applications safely, incrementally, and confidently.

This strategy is battle-tested, production-friendly, and ideal for organizations that want the benefits of microservices without the pain of starting over.