DEV Community

Cover image for Migration from .NET 4.7 to .NET 10
Mo
Mo

Posted on

Migration from .NET 4.7 to .NET 10

Travels in Time:

The Great Migration from .NET Framework 4.7 to .NET 10 ๐Ÿš€

All of us have encountered this situation: inheriting a project that has remained untouched for years, only to discover it is now outdated. Recently, I was assigned to such a project with a clear directive to modernise a legacy application built on .NET Framework 4.7 and successfully migrate it to the latest LTS release, .NET 10.

It was a journey filled with architectural archaeology, AI tooling, and some tough decisions. Here is the story of how we managed the upgrade of this legacy application using Visual Studio 2026, and what we learned along the way.


๐Ÿง Phase 1: The Archaeology

My journey began with a classic induction meeting with my Line Manager and Product Owner. Once the pleasantries were done, I popped the hood to see how the project was structured.

As expected with legacy code, there wasn't much of a "structure" to speak of. It was a flat architecture where almost all business logic lived directly inside the Controllers. Even worse, database contexts were being instantiated right there in the controller methods, something like this:

public class LegacyController: Controller {
    public ActionResult Index() {
        // Direct instantiation inside the controller? Check.
        using (var db = new MyDbContext()) { ... }
    }
}
Enter fullscreen mode Exit fullscreen mode

I knew that if I started refactoring immediately, I would generate a massive amount of changes that would be impossible to review properly, increasing the risk of failure.

The Initial Health Check

I decided to run the application to understand the flow without getting bogged down in the nitty-gritty of every single class. I also ran the existing unit tests. Unsurprisingly, red lights flashed everywhere.

The project lacked a proper CI/CD pipeline, so over time, business logic had drifted, while the tests had been forgotten.


๐Ÿ“‹ Phase 2: The Battle Plan

I went back to the Azure Board and tagged my Line Manager and PO with a plan. I proposed a strict order of operations to mitigate risk:

  1. Stabilize: Pass all current unit tests to ensure the application works before we touch the framework.
  2. Upgrade: Move the project directly from .NET Framework 4.7 to .NET 10.
  3. Modernise: Once stable on .NET 10, implement a proper CI/CD pipeline in Azure DevOps.

I spent a few days fixing bugs in the test suite until everything was green. Only then was I ready for the big lift.


๐Ÿ›  Phase 3: The Upgrade (Dependencies & AI Tools)

Using the newly released Visual Studio 2026, I started by auditing our NuGet packages and third-party references.

The Third-Party Challenge

One significant hurdle was a reference to Excel-DNA. When upgrading, checking vendor compatibility is non-negotiable. I had to comb through their documentation to find their specific upgrade process for .NET 10 compatibility.

The Entity Framework Dilemma

We were also using Entity Framework 6 (EF6). While EF6 is technically compatible with .NET 10, the long-term goal is obviously Entity Framework Core. However, trying to do that migration simultaneously would have blown up the scope. My manager and I agreed: get to .NET 10 first, upgrade to EF Core later.

AI vs. Legacy Tools

Visual Studio 2026 offers a tool called Modernizer, which leverages AI (ChatGPT, Gemini, Claude) to handle upgrades.

Tool Verdict
Modernizer (AI) Fantastic for simple class libraries. It proposed excellent upgrade plans and did the heavy lifting.
Legacy Upgrade Assistant Necessary for the complex UI projects. The AI struggled with our old AngularJS/MVC mix, so I had to enable this legacy tool via Tools > Options.

๐Ÿ— Phase 4: Execution

Step 1: Low-Hanging Fruit

I started with the solution's four projects. Three were simple class libraries, so I used the Modernizer AI tool to upgrade them to .NET 10 first.

Pro Tip: When upgrading, resist the urge to use new features immediately. .NET 10 has cool toys like file-scoped namespaces, but mixing feature changes with framework upgrades creates noisy Pull Requests (PRs). I kept the code changes minimal so my team could actually review the PR.

Step 2: The Web Project (The Beast)

The main website was an ASP.NET MVC application with AngularJS. The Legacy Upgrade Assistant handled the C# conversion well, but it had no idea what to do with the UI.

The Bundling Problem:
Old ASP.NET had built-in bundling for CSS and JS. .NET 10 doesn't work that way. I had to:

  1. Find npm equivalents for our NuGet client-side packages.
  2. Implement a new build process.

I decided to use Gulp to compile our TypeScript and LESS files and bundle them. I utilised AI heavily to generate the Gulp tasks (which worked perfectly), creating a single output file referenced in our index.html.

Step 3: The Inevitable Refactor

Here is where I had to break my own rule about "minimal changes." The old code was so non-SOLID that I literally couldn't inject the services I needed into the controllers.

I had to refactor the presentation layer, introducing the Unit of Work pattern and cleaning up the dependency injection. It made the PR larger, but it was unavoidable to get the application running.


โœ… Phase 5: Crossing the Finish Line

With the refactoring done, I ran the project. Miraculously (or perhaps due to the preparation), it worked.

I performed end-to-end testing, deployed to the test environment, and handed it over to QA. Everything looked green. I opened the PR, which was only "50% of the job" considering the future work needed, but the platform was now on .NET 10.


๐Ÿ”ฎ What's Next?

We successfully reached .NET 10, but the journey isn't over. We still need to upgrade to EF Core and add observability.

However, the business has shifted priorities. The old AngularJS frontend is now a security vulnerability. We aren't just upgrading to modern Angular; my manager wants a complete rewrite of the presentation layer using React.

Thereโ€™s just one catch: I don't know React very well yet.

Itโ€™s going to be a challenging task, but I plan to tackle it head-on. Stay tuned, Iโ€™ll be sharing how I manage that learning curve in my next post.

Happy coding!

Top comments (0)