Abstract: We practically show examples of 15 different .NET8/9 build modes, including Framework-Dependent and Framework-Independent, how to bundle an app into a single file, how to trim app bundles from unused libraries, and how to build an Ahead-of-time (AOT) precompiled app.
1. .NET8/9 toolset supports different build/publish/deployment modes
I was experimenting with different project properties/flags, and I developed several proof-of-concept build projects showcasing different build/publish/deployment modes available in .NET8/9, using Microsoft tools.
1.2. Articles in this series
For technical reasons, I will organize this text into several articles.
- .NET8/9 – Testing different Build/Deployment modes – Part 1
- .NET8/9 – Testing different Build/Deployment modes – Part 2
- .NET8/9 – Testing different Build/Deployment modes – Part 3
- .NET8/9 – Testing different Build/Deployment modes – Part 4
- .NET8/9 – Testing different Build/Deployment modes – Part 5
- .NET8/9 – Testing different Build/Deployment modes – Part 6
2. New build configurations for NET 8.0.11 and NET 9.0.0
New build configurations/scripts for NET_8.0.11/SDK_8.0.404 and NET_9.0.0/SDK_9.0.101 environments are here. Build types and the rationale are as before, just some new build tricks were made. Any better C# developer should be able to understand these build settings.
3. Code on GitHub
I am putting example build projects on GitHub [99]. There are three solutions.
- BundleExample01_NET_8.0.0_SDK_8.0.100.sln (read comments; this is broken in .NET 8.0.11)
- BundleExample01_NET_8.0.11_SDK_8.0.404.sln (locked to SDK_8.0.404)
- BundleExample01_NET_9.0.0_SDK_9.0.101.sln (locked to SDK_9.0.101)
![Bundle example]()
![Example 1]()
![Example 2]()
4. Conclusion
In this series of articles, we showed 15 different ways to build a .NET8/9 application, depending on the options wanted. There are probably more options or combinations of build properties/flags, but we can call this proof-of-concept testing successful and broad enough. We got most of the build/publish options working properly, according to the documentation.
I was in these articles aiming for some “intermediate level of practical skills” that a modern C#/.NET developer should have. Of course, this is a very interesting topic for every software engineer to get familiar with.
It was a bit of a surprise to discover that build settings are a bit of a “moving target”, and that build tools behavior changed between .NET 8.0.0 and .NET 8.0.11 and that I needed to change my build scripts accordingly.
One very interesting technology offered as a part of .NET8/9 environment is a “ReadyToRun” build option, which is a form of ahead-of-time (AOT) compilation. More details can be found at [7]. Looks to me like a complicated and serious topic, to really understand how it works from the inside. But I do not see the point of really studying it in detail unless you work in Microsoft in their .NET runtime/core department. An average C#/.NET engineer just needs to know how to activate properly the build options and benefits of it.
We also showed how to do a native Ahead-Of-Time compilation (AOT) deployment model. That can be attractive in some cases too.
5. References
[1] .NET application publishing overview
https://learn.microsoft.com/en-us/dotnet/core/deploying/
[2] Self-contained deployment runtime roll forward
https://learn.microsoft.com/en-us/dotnet/core/deploying/runtime-patch-selection
[3] https://www.red-gate.com/products/smartassembly/
[4] https://learn.microsoft.com/en-us/dotnet/core/deploying/single-file/overview?tabs=cli#api-incompatibility
[5] https://www.jetbrains.com/decompiler/
[7] https://devblogs.microsoft.com/dotnet/conversation-about-ready-to-run/
[99] https://github.com/MarkPelf/ArticlesCode , folder 86_Net8BuildModes_Part6