The ideal method for creating cloud-native, scalable, and maintainable systems is microservices architecture. Microservices are not the initial state of the majority of real-world systems, though. They begin as monolithic programs that run crucial business logic and were frequently created years ago.

It's a frequent misperception that implementing microservices necessitates a total overhaul. Rewriting a monolith from scratch is actually costly, hazardous, and rarely successful.
This article describes how to use the Strangler Fig Pattern, a secure and tried-and-true migration technique, to create microservices within an existing monolith in .NET Core.
What Is a Monolithic Application?
A monolith is an application where:
- All features live in a single codebase
- Components are tightly coupled
- Deployment happens as one unit
Challenges of a Monolith
- Slow deployments
- Difficult scaling
- High risk when changing code
- Hard to adopt new technologies
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:
- Business downtime
- Loss of domain knowledge
- New bugs and regressions
- Long time-to-market
Instead of replacing the monolith, a gradual migration is the safest approach.
What Does “Microservices via Monolith” Mean?
“Microservices via Monolith” means:
- Keeping the existing monolith alive
- Gradually extracting features into microservices
- Letting both systems coexist during the transition
This approach allows teams to:
- Reduce risk
- Deliver value incrementally
- Learn microservices without breaking production
The Strangler Fig Pattern
The Strangler Fig Pattern is a migration strategy where:
- New features are built as microservices
- Existing functionality is slowly moved out
- 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:
- Separate business logic from controllers
- Use layered architecture (API, Application, Domain, Infrastructure)
- Identify bounded contexts
Tip: If your monolith is already in ASP.NET Core, you are halfway there.
Step 2: Identify a Candidate Microservice
Good candidates:
- Low coupling with other modules
- Clear business boundaries
- High change frequency
Examples:
- Authentication
- Notifications
- Reporting
- Payments
Step 3: Create a New ASP.NET Core Microservice
Create a new project:
dotnet new webapi -n NotificationService
This service should:
- Own its database
- Expose REST APIs
- Be independently deployable
Step 4: Route Traffic Using an API Gateway
Use tools like:
- YARP (Yet Another Reverse Proxy)
- Ocelot
- Azure API Management
Example with YARP:
/api/notifications → Microservice
/api/orders → Monolith
This makes the migration invisible to clients.
Step 5: Data Management Strategy
Avoid sharing databases.
Common approaches:
- Database per service
- Data synchronization via events
- Read replicas for legacy data
Never let microservices directly access the monolith database.
Step 6: Communication Between Monolith and Microservices
Preferred methods:
- REST APIs
- Asynchronous messaging (RabbitMQ, Azure Service Bus)
Example:
- Monolith publishes OrderCreated event
- Microservice listens and processes it
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:
- Loose coupling
- Independent scaling
- Faster deployments
Benefits of Microservices via Monolith
✔ Lower migration risk
✔ Continuous delivery
✔ Independent scaling
✔ Better maintainability
✔ Cloud readiness
Common Mistakes to Avoid
❌ Extracting too many services at once
❌ Sharing databases
❌ Overusing synchronous calls
❌ Ignoring observability (logs, metrics, tracing)
Tools Commonly Used in .NET Core Microservices
- ASP.NET Core
- Docker
- Kubernetes
- YARP / Ocelot
- Serilog
- OpenTelemetry
- RabbitMQ / Azure Service Bus
When Should You Stop?
The migration ends when:
- The monolith no longer handles business logic
- Remaining code is minimal or retired
- All core features live in microservices
- 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.