- •Table of Contents
- •About the Author
- •Acknowledgments
- •Introduction
- •Version Support
- •Supported Versions
- •A Unified Platform
- •Roadmap
- •Supported Operating Systems
- •Command Line Interface
- •Desktop Development
- •Blazor
- •MAUI
- •Wrapping Up
- •.NET 6 Architecture
- •Runtimes
- •CoreCLR
- •Mono
- •WinRT
- •Managed Execution Process
- •Desktop Packs
- •Wrapping Up
- •Dotnet New
- •Dotnet Restore
- •NuGet.config
- •Dotnet Build
- •Dotnet Publish
- •Dotnet Run
- •Dotnet Test
- •Using the CLI in GitHub Actions
- •Other Commands
- •Wrapping Up
- •WinAPI
- •WinForms
- •STAThread
- •WinForms Startup
- •DPI Mode
- •Responding to Scale Events
- •Visual Styles
- •Text Rendering
- •The Message Loop
- •The Form Designer
- •WPF Startup
- •XAML Layout
- •Visual Tree
- •Data Binding
- •Windows App SDK
- •Building a Windows App SDK application
- •Using Windows APIs with Windows App SDK
- •Packaging
- •Migrating to .NET 6
- •Upgrade Assistant
- •Wrapping Up
- •Blazor WebAssembly
- •Creating a Blazor Wasm Project
- •Blazor Progressive Web Apps
- •Exploring the Blazor Client Project
- •Blazor in .NET 6
- •Blazor Component System
- •Creating Blazor Pages
- •Running a Blazor App
- •Blazor Server
- •SignalR
- •Blazor Desktop
- •Wrapping Up
- •Project Structure
- •Exploring MAUI
- •The Cross-Platform World
- •Application Lifecycle
- •MVVM
- •MVVM Toolkit
- •Wrapping Up
- •Model-View-Controller
- •Routing
- •Views
- •Controllers
- •Controller-Based APIs
- •Minimal APIs
- •Wrapping Up
- •Web Apps
- •Creating an App Service
- •Static Web Apps
- •Web App for Containers
- •Docker
- •Azure Functions
- •Deploying Azure Functions
- •Wrapping Up
- •Record Types
- •Monolith Architecture
- •Microservices
- •Container Orchestration
- •Kubernetes
- •Docker Compose
- •Dapr
- •Installing Dapr
- •Dapr State Management
- •Wrapping Up
- •Roslyn
- •Compiler API
- •Diagnostic API
- •Scripting API
- •Workspace API
- •Syntax Tree
- •Roslyn SDK
- •Source Generators
- •Writing a Source Generator
- •Debugging Source Generators
- •Wrapping Up
- •Garbage Collector
- •The Heap
- •The Stack
- •Garbage Collection
- •A Look at the Threadpool
- •Async in .NET 6
- •Await/Async
- •Cancellations
- •WaitAsync
- •Conclusion
- •Index
Chapter 2 Runtimes and Desktop Packs
Figure 2-1. .NET unification
What the image portraits is the .NET abstraction layer. We write the same .NET code everywhere, but depending on the compile target, a different compiler will be used. When executing a .NET application, a different runtime may be used depending on the platform it is being executed on. Let’s take a command line application, for example, a command line has no UI so no platform-specific code to render screens is necessary, meaning that the same CLI application can run on Windows, Linux, and macOS. When compiling this application, the default .NET 6 compiler will be used, resulting in one executable. Running this executable on Windows will be handled by the common language runtime, CoreCLR. On macOS and Linux, however, this will be handled by Mono, completely transparent to developers and users.
Runtimes
The .NET languages are managed languages, meaning that code you write in C# gets compiled down to intermediate language. Once your code gets executed, that
intermediate language is compiled into machine code by the just in time compiler, or JIT. That JIT is part of the common language runtime, or CLR.
22
Chapter 2 Runtimes and Desktop Packs
When writing .NET code, we don’t program against an operating system; the system APIs in C# don’t target Windows/Linux/macOS directly; instead, they target the API surface of the common language runtime called CoreFX. CoreFX is the newer name of what used to be the Base Class Library or BCL. It includes the System.* namespaces that we use all the time to call platform or framework APIs. The CLR calls into the operating system’s APIs via CoreFX to perform the tasks requested by the developer. In this way, the CLR functions as an abstraction layer, enabling cross-platform code.
The CLR also gives us memory management, keeping track of objects in memory and releasing them when they are no longer needed. This garbage collection is part of the runtime and is what makes .NET languages managed, compared to unmanaged languages like C and C++ where you must do your own memory management.
.NET 6 contains two default runtimes. Depending on the platform you are running your code on, it will be executed by either CoreCLR or Mono.
The .NET 6 runtimes are open source and available at https://github.com/dotnet/runtime.
CoreCLR
The CoreCLR is the .NET 6 version of the classic CLR. It is the common language runtime used for running .NET code on Windows. No matter if it is a desktop application, web application, or console app, if any of these run on Windows, they will use the CoreCLR.
Mono
Mono started as an open-source project to bring .NET and its languages to Linux. Mono was based on the publication of the .NET open standard. The first version of Mono
was released in 2004. The maintainers of the Mono open-source project were a small company called Ximian. Ximian and thus Mono were acquired by Novell, Novell was acquired by Attachmate, and the future of Mono seemed very dark. Some people from Ximian formed a new company called Xamarin. Xamarin continued the work on Mono, eventually releasing a mobile cross-platform framework based on Mono. Microsoft became the owner of the Mono project after acquiring Xamarin in 2016.
Mono currently ships as part of .NET 6; it is the default runtime when not running on a Windows-based operating system.
23