🌿 Modernizing .NET — Part 30: Strangler Fig Architecture
How to migrate ASP.NET Framework to ASP.NET Core one safe slice at a time instead of betting on a big rewrite.
🌿 Modernizing .NET — Part 30: Strangler Fig Architecture

When this series started, I thought it would end around Part 28. But the topic became more useful than expected, because modernization is not only about replacing APIs. After you replace System.Web, WebClient, SmtpClient, WCF, config files, serialization, and storage patterns, a larger question appears:
How do you move a real ASP.NET Framework application to ASP.NET Core without rewriting everything at once?
That is where architecture becomes important. The first architecture pattern worth naming is Strangler Fig: an incremental migration strategy where the new system grows around the old system, replaces it piece by piece, and eventually allows the legacy parts to be removed.
🧭 Why architecture matters now
The previous articles focused on practical migration blocks: wrappers, compatibility layers, service interfaces, fallback behavior, and ASP.NET Core replacements for older .NET Framework patterns.
Those techniques are useful individually, but together they describe a bigger migration shape.
A large ASP.NET Framework application usually cannot be moved in one clean step. Too many things change at the same time:
- framework
- runtime
- hosting model
- authentication behavior
- HTTP pipeline
- configuration
- dependency injection
- serialization
- external service clients
- legacy business logic
A big-bang rewrite forces all of those changes into one release. That increases risk because when something breaks, it is difficult to know whether the problem came from the new framework, new infrastructure, new code, changed behavior, or a misunderstood legacy dependency.
Strangler Fig reduces that risk by migrating one slice at a time.
🌿 What Strangler Fig means
The name comes from the strangler fig tree. It grows around an existing tree, gradually surrounds it, and eventually replaces it.
In software, the same idea looks like this:
Before:
Users
↓
ASP.NET Framework application
↓
Legacy code, System.Web, WebForms, WCF, old config, old libraries
During migration, the system gains a boundary in front of, or around, the legacy application:
During migration:
Users
↓
Routing / proxy / compatibility layer
├─ old feature still handled by ASP.NET Framework
└─ migrated feature handled by ASP.NET Core
After enough slices are migrated, the old application disappears from the main path:
After migration:
Users
↓
ASP.NET Core application
↓
Modernized services, middleware, DI, HttpClientFactory, Redis, CoreWCF, etc.
The important point is not the diagram. The important point is the release strategy: identify one feature, put a boundary around it, build the replacement, route only that feature to the new implementation, verify behavior, then continue.
🧱 The migration pattern
A Strangler Fig migration usually follows this sequence:
Step 1: Identify one legacy feature
↓
Step 2: Put a boundary around it
↓
Step 3: Build the ASP.NET Core replacement
↓
Step 4: Route only that feature to the replacement
↓
Step 5: Keep fallback to old behavior if needed
↓
Step 6: Remove old implementation after confidence grows
This is why many earlier migration techniques fit together.
Legacy feature Migration move
-----------------------------------------------------------------
System.Web.HttpContext Add compatibility wrappers
WebClient / RestSharp Replace behind service interfaces
SmtpClient Replace with MailKit wrapper
BinaryFormatter Introduce protobuf with fallback
Dictionary-based storage Move to Redis with fallback
.asmx / WCF / SOAP Move to CoreWCF while preserving contracts
.aspx pages Route old URLs to new ASP.NET Core handlers
Old config files Load through custom configuration providers
Each move creates a boundary. The boundary allows old and new code to coexist while the implementation changes behind it.
🧩 A concrete example: .aspx pages
A WebForms migration is a good example.
A big rewrite would try to replace the entire WebForms application in one step. That sounds clean, but it is usually risky because old URLs, postback behavior, session usage, authentication assumptions, and business logic are often mixed together.
A Strangler Fig approach keeps the outside contract stable while changing the inside.
Old request:
/SomePage.aspx
↓
ASP.NET WebForms page
During migration, the same URL shape can be preserved while different request types move to different implementations:
GET /SomePage.aspx
↓
Static HTML or migrated frontend page
POST /SomePage.aspx
↓
ASP.NET Core controller
↓
Modern service logic
From the user’s point of view, the URL still exists. From the system’s point of view, the implementation is no longer tied to WebForms.
That is the core migration advantage: the external contract does not need to change at the same time as the internal architecture.
🔌 Another example: HttpContext.Current
The same idea applies to System.Web.HttpContext.Current.
A big-bang rewrite would require every legacy usage to be replaced immediately:
HttpContext.Current.Request.UserHostAddress
In a Strangler Fig migration, you can introduce a compatibility boundary instead:
Legacy code expects:
System.Web.HttpContext.Current
Migration layer provides:
System.Web.HttpContext.Current
↓
wrapper around
ASP.NET Core IHttpContextAccessor
This does not make System.Web modern. It creates a controlled bridge so legacy code can keep compiling while the real implementation gradually moves toward ASP.NET Core patterns.
That bridge should not live forever, but it can make the migration possible.
⚖️ Tradeoffs and lessons
Strangler Fig is not free.
The benefits are clear:
- lower migration risk
- faster partial delivery
- easier rollback
- stable business behavior during migration
- coexistence between legacy and modern code
But the costs are real too:
- temporary duplication
- routing and proxy complexity
- compatibility layers that can accidentally become permanent
- more architectural mess during the transition
- the need for discipline when deleting old code
That last point matters. A Strangler Fig migration is successful only if the old tree is eventually removed. Otherwise, the system can end up with both the legacy complexity and the migration complexity.
✅ Summary
Strangler Fig is the strategy of surrounding an old ASP.NET Framework application with ASP.NET Core replacements, routing one feature at a time to the new implementation, and deleting the legacy code only after each migrated slice is stable.
It is probably the best architectural label for the migration described throughout this series.
Earlier articles showed the individual techniques. This article names the architecture behind them: do not rewrite everything at once, create boundaries, migrate one slice, verify behavior, and keep moving.
🔜 Next Post
In the next article, we will continue the architecture discussion with Ports and Adapters, also known as Hexagonal Architecture.
🔌 Modernizing .NET — Part 31: Use Ports and Adapters to Make ASP.NET Core Migration Incremental
Let’s connect: 🔗 LinkedIn 🌐 Bluesky 🐘 Mastodon
Follow me for more deep dives into .NET, AWS, Python, LangChain, GenAI, tech workflows, and the occasional pixel art adventure.
메타데이터
- post_id
- 903da2ce1e9a
- slug
- modernizing-net-part-30-strangler-fig-architecture-903da2ce1e9a
- url
- https://medium.com/@michael.kopt/modernizing-net-part-30-strangler-fig-architecture-903da2ce1e9a
- canonical_url
- https://medium.com/@michael.kopt/modernizing-net-part-30-strangler-fig-architecture-903da2ce1e9a
- author_url
- https://medium.com/@michael.kopt
- status
- ok
- fetched_at
- 2026-07-09 20:42:47