.NET Framework Migration – From 4.8 to .NET 8 with Clean Architecture

05/19/2025
2 minute read

Final Project Structure

The new architecture follows the Clean Architecture pattern, with clearly separated layers and responsibilities:

Component Description
Core DI lifetimes and extension methods
Model Entities and DTOs
Logic Use cases and framework logic
WinServices Console apps and background services
Websites Three web apps: Public API, Customer Portal, Admin Panel

Housekeeping & Cleanup

  • Removed outdated test projects and proof-of-concepts, reducing total projects from 75 to 60.
  • Organized the solution into structured folders aligned with architectural layers.

Migration POC

  • Reviewed official .NET documentation and created proof-of-concepts for background services and web apps in the new environment.

Migration Strategy

  • Inside-out approach: Migrated class libraries to .NET Standard 2.0 first.
  • Moved System.Web dependencies out of reusable libraries and confined them to web-level projects.

Migration Priorities

  1. Queue Handler Service – Rebuilt critical parts and offloaded some components to AWS Lambda.
  2. API Layer – Migrated service endpoints and core logic to .NET 8.
  3. Admin Panel – Updated dashboard and admin tools for compatibility.

Key Challenges & Solutions

Decoupling web dependencies

System.Web dependencies were tightly integrated across the codebase.

Solution: Used Unity DI to define interfaces and inject platform-specific implementations, allowing lower layers (Core, Model, Logic) to compile independently using .NET Standard.


Razor Template Engine

The legacy Razor engine was central to generating reports, customer views, and emails.

Solution: Replaced the built-in Razor engine with RazorEngineCore, an open-source NuGet package supporting .NET Standard and .NET 8.


Replacing Legacy Charting

System.Web.UI.DataVisualization.Charting was incompatible with .NET 8.

Solution: Migrated all reporting and visual chart elements to ScottPlot, which is actively maintained and cross-platform compatible.


Migrating Entity Framework 6

The original codebase relied heavily on EF6.

Solution: Used the latest version of Entity Framework 6, which supports .NET 8, to maintain compatibility without rewriting all DB logic from scratch.


Async in Sync Contexts

Many updated NuGet packages (like Amazon.S3) required async calls.

Solution: Used Nito.AsyncEx to bridge async calls within sync workflows, avoiding large-scale rewrites while maintaining stability.


Additional Contributions

  • Built a shared configuration layer for both legacy and .NET 8 environments.
  • Ported Unity-based DI configuration to work seamlessly in .NET 8.

This migration demonstrates deep knowledge of architectural refactoring, legacy modernization, cross-platform dependency management, and incremental delivery within enterprise systems.

An error has occurred. This application may no longer respond until reloaded. Reload x