Coding Once, Thriving Everywhere: A Deep Dive Into .NET MAUI’s Cross-Platform Magic
This article will provide insights into the fundamentals of the .NET MAUI platform, followed by an exploration of the project structure within a sample MAUI project.
Join the DZone community and get the full member experience.Join For Free
Developed by Microsoft, the .NET MAUI (multi-platform app UI) is an open-source framework to build native mobile and desktop applications for multiple platforms, including Android, iOS, macOS, Windows, and more, and that too, using a single codebase. Unlike the Xamarin forms, where developers have to maintain a separate codebase for each targeted platform.
An Overview of .NET Framework
If you are aware of what .NET framework is and how it works, then you can skip this section and jump to “How It Works.”
The .NET Framework is a software development platform created by Microsoft. It provides a comprehensive and consistent programming model for building and running applications across various Microsoft Windows platforms, including desktop, web, and mobile.
Here are some key features and components of the .NET Framework:
- Common Language Runtime (CLR): The CLR is the foundation of the .NET Framework. It provides core services like memory management, garbage collection, and exception handling. It also enables language interoperability, allowing multiple programming languages to be used together within the same application.
- Base Class Library (BCL): The BCL is a collection of pre-built classes, types, and APIs that provide a wide range of functionality to developers. It includes classes for file I/O, networking, data access, cryptography, threading, and much more. The BCL offers reusable components that simplify application development.
- Language support: The .NET Framework supports multiple programming languages, including C#, Visual Basic .NET (VB.NET), and F#. Developers can choose their preferred language to write code and take advantage of the rich tooling and libraries available for each language.
- Framework Class Library (FCL): The FCL is a collection of libraries and frameworks built on top of the BCL. It provides additional functionality for specific types of applications, such as Windows Presentation Foundation (WPF) for desktop applications, ASP.NET for web development, and Windows Communication Foundation (WCF) for building service-oriented applications.
- Deployment and execution: .NET Framework applications are typically deployed as compiled assemblies (.exe or .dll files) along with any required dependencies. At runtime, the assemblies are executed by the CLR, which just-in-time (JIT) compiles the IL (Intermediate Language) code into native machine instructions.
How .NET MAUI Works
After you write .NET MAUI code (mostly in C#), the following steps occur:
Building the Application
- The code, including the references to the BCL classes, is compiled using the .NET build tools or an integrated development environment (IDE) like Visual Studio.
- During the build process, the C# code is transformed into an Intermediate Language (IL) or Common Intermediate Language (CIL). This IL is platform-agnostic and can run on any platform with a compatible .NET runtime.
- We can also install and enable Ahead-of-Time compilation (AOT). If this is enabled, then steps 2 and 3 below will be skipped, and .NET MAUI will generate native code for the targeted environment from IL.
- When AOT is activated, the Mono runtime is utilized to transform .NET MAUI code into native code for iOS and Android platforms, while the .NET CLR is employed for Windows to achieve the same conversion.
- The IL code, along with the referenced BCL assemblies, is then compiled into platform-specific binaries for each target platform.
- For Android, the .NET MAUI tooling packages up the IL code and XAML, along with any necessary .NET libraries, into an Android Package (APK). This is an archive file used to distribute Android apps.
- For iOS, Apple doesn’t allow JIT to run on iOS devices. Due to this, you will not be able to run your app on iOS. For Apple, please use Ahead-of-Time compilation.
- For Windows, the IL code can be Just-In-Time (JIT) compiled at runtime or ahead-of-time (AOT) compiled into native instructions using the .NET Native compiler using Windows UI 3 (WinUI 3) library.
Note: Android toolchain (.NET for Android) and Windows UI 3 (WinUI 3) library are part of the .NET framework (6 or greater).
Execution and Interaction With BCL
- The compiled application, along with the required BCL assemblies, is deployed and executed on the respective target platforms.
- When the app is launched on the Android device, the .NET MAUI runtime handles just-in-time (JIT) compilation of the IL code into native machine code that can be executed.
- At runtime, the application can interact with the BCL classes and APIs, leveraging their functionality to perform various tasks.
- For example, if your application needs to read from a file, you can utilize BCL classes like `System.IO.File` to access file I/O operations.
- Similarly, if your application requires networking capabilities, you can use classes from the `System.Net` namespace provided by the BCL to handle networking tasks.
- The .NET MAUI rendering engine uses the XAML markup to construct a native user interface for the Android platform.
During the platform-specific compilation process, any platform-specific resources and assets (such as images, layouts, and configuration files) specified in the code are also included in the output. Additionally, the necessary platform-specific runtime libraries and dependencies are bundled with the application to ensure it runs correctly on each target platform.
Below is a diagram illustrating the steps mentioned previously:
Diagram was prepared using Draw.io
Installation and Setup
We can create a .NET MAUI project using Visual Studio Community edition. Click here to download the same. Please note that we must install 2022 to work with .NET MAUI. The link will download Visual Studio Installer. Double-click the file to run the program and select “.NET Multi-platform UI App” under the “Desktop and Mobile” option (as shown in the image below in the red square.).
This will start downloading and installation of all the required tools for building a mobile app. After the setup is finished, you are ready to develop a mobile app. Isn’t it so easy? Open the Visual Studio Community edition and click on the “Create a new project” link as shown below:
Give the project and solution name as “MauiApp1”.
Project Structure of .NET MAUI Application
The typical structure of the application will look something like this:
Let’s discuss each folder and its contents.
Dependencies: This folder contains all the necessary SDKs, NuGet packages, Libraries, and components that are required to run and develop the application.
Properties: It contains only one file, “launchSettings.json,” and it is used to launch and debug the application. Generally, it is used to add environment variables, arguments, etc. See an example below:
The application has been configured to run on Browser on port 80 with the environment variable “ASPNETCORE_ENVIRONMENT” with the value “Development.” The command “dotnet” with the argument “run” will be used when we run the application. Please note that this file may be very simple initially. However, as we progress in development, we have to frequently update the file to change/add configuration values.
This folder contains subfolders for each environment. Inside these subfolders, we have platform-specific code, resources, dependencies, and configurations. This separation allows developers to customize the behavior and appearance of the application on different platforms while maintaining the shared codebase for common functionality.
The common usage can include conditional compilation to exclude or include specific sections of code, performance optimization configuration based on the platform, and platform-specific testing configuration.
This folder holds various non-code assets, such as images, icons, styles, and localization files. Note that assets stored in these folders are platform-independent. This means that the same resources can be used across different target platforms (iOS, Android, Windows) without duplicating files or writing platform-specific code.
Now let’s see what those independent root-level files are for:
- App.xaml: This file serves as a central location for defining shared resources, configurations, and behaviors that apply across the entire application. It helps ensure consistency, simplifies initialization and cleanup, and allows you to handle important lifecycle events effectively.
- AppShell.xaml: This file is used to define the navigation for the app. The order of the child elements in the Shell element determines the order in which the pages are displayed.
- MainPage.xaml: This file acts as the canvas for your app's initial user interface and provides the starting point for navigation and user interaction. It's the place where you set the tone for your app's user experience and define the first impressions that users will have when they launch your application. For example, it can include containers like StackLayout, Grid, or RelativeLayout to arrange various UI elements, such as buttons, labels, images, and other controls.
- MauiProgram.cs: This file contains the main class “MauiProgram,” which serves as the start of the application and is used to configure fonts, services, and other third-party libraries.
In essence, .NET MAUI empowers developers to create versatile, efficient, and stunning applications that target multiple platforms without compromising on native performance. Its project structure, rendering engine, and seamless integration into the .NET ecosystem set the stage for a new era of cross-platform development, inviting developers to craft applications that delight users across diverse devices and operating systems. As the technology landscape continues to evolve, .NET MAUI emerges as an indispensable tool in the modern developer's toolkit, bridging the gap between platform diversity and code simplicity.
Opinions expressed by DZone contributors are their own.