Migrating strategy when upgrading from .NET framework to .NET 8 using .NET Framework compatibility mode
A while back, I have helped upgrading one relatively large solution from .NET Framework 4.7.2 to .NET 8 in my company. I would like to share the strategy we used and hope this can help someone on a similar path.
Context
We have a solution that are in active development that is in .NET Framework 4.7.2. We decided to upgrade it to .NET 8 for performance reason and potential of deploying to Linux container down to line.
The solution is a bunch of services projects deployed as windows services. The services have dependency on custom domain libraries within and outside of the solution. We also have unit tests and integration tests projects depending on the services projects.
Some of the domain library within the solution is also published as internal NuGet packages for other internal solutions.
Incremental upgrade
If your solution is small, you can probably upgrade to .NET 8 and fix all the issues in one go. However, that is rarely the case for business applications. The way we approach it is upgrading incrementally.
With the introduction of .NET Framework compatibility mode, we can now reference .NET Framework project from .NET standard or .NET Core project. This allow us to upgrade incrementally from the top of the dependency tree and work downward.
So, we upgraded the test projects first while keeping everything else in .NET Framework. The benefit of upgrading tests first is to provide some confidence on how feasible is the upgrade while keeping the risk relatively low because none of the production code is actually being upgraded at first.
.NET Upgrade assistance
One tool that we found useful is the .NET Upgrade assistance. You can use it through CLI or Visual Studio extension. I used it through Visual Studio and it does help.
Potential issues
Although you can reference .NET Framework project from .NET standard or .NET Core project. There is no guarantee that it will work. Microsoft make it clear that it may not be fully compatible, especially when you use framework specific API within the referenced project.
One way to resolve the issue is upgrading the referenced project having issue to .NET standard 2.0 and replacing the .NET Framework specific API. Depending on what you are replacing, it can be easy or difficult. Luckily for us, it was not too difficult.
.NET standard vs multi target
The other decision you will have to make is whether changing the library that you are sharing to other solutions to target .NET standard 2.0 or to multitarget.
In general, I suggest choosing .NET standard 2.0. Be careful, it should be .NET standard 2.0 but not 2.1. The reason being 2.0 is the last version that support both .NET Core and .NET Framework. .NET standard 2.0 is the most compatible framework that should support the most framework.
One reason to multi target is when you need to support older version of .NET Framework. .NET standard 2.0 only support .NET Framework higher then 4.6.1. If you need to support, say, .NET Framework 4, multi target is your only option (See How to multitarget).
When you multitarget, I suggest multitarget .NET Framework and .NET standard 2.0 instead of .NET Framework and .NET 8. This should give you less pain when you need to upgrade to future .NET version down the line.
Conclusion
Migrating big solution from .NET Framework to .NET 8 is not easy task and I hope this can give you some insight into where to start. Good luck!