Fundamentals & Architecture
7 questions found.NET Multi-platform App UI (.NET MAUI) is Microsoft's cross-platform framework for building native mobile and desktop apps from a single C# and XAML codebase. It targets Android, iOS, macOS (via Mac Catalyst), and Windows (via WinUI 3) from one project, and is the evolution of Xamarin.Forms.
Real-world example A startup builds one MAUI app and ships it to the App Store, Google Play, and the Microsoft Store, sharing roughly 90% of the code instead of maintaining three native teams.
Common follow-ups: How does MAUI differ from Xamarin.Forms? | Which platforms does MAUI support?
Xamarin.Forms vs MAUI Single Project Cross-platform
MAUI is the successor to Xamarin.Forms. Key differences: MAUI uses a single project with multi-targeting instead of one project per platform; it uses a new handler-based architecture instead of renderers; it ships as part of the .NET SDK workload rather than a NuGet package; and it adds first-class desktop support (WinUI 3 and Mac Catalyst).
Real-world example A team migrating a Xamarin.Forms app consolidates five platform projects into one MAUI project, dropping custom renderers in favor of lighter-weight handlers.
Common follow-ups: What is the handler architecture? | Why did Microsoft replace renderers?
Xamarin.Forms vs MAUI Handlers Single Project
MAUI uses one .csproj that multi-targets several platforms. Platform-specific code, resources, and entry points live under a Platforms/ folder, while shared code, images, fonts, and app icons are declared once and processed per platform at build time. This replaces the multiple head projects Xamarin required.
<TargetFrameworks>net8.0-android;net8.0-ios;net8.0-maccatalyst</TargetFrameworks>
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">
$(TargetFrameworks);net8.0-windows10.0.19041.0
</TargetFrameworks>
Real-world example One project outputs an .apk, an .ipa, and an .msix from the same source tree during CI.
Common follow-ups: Where does platform-specific code go? | How does multi-targeting work?
Multi-targeting Platforms folder Project Structure
Handlers map a cross-platform virtual control (e.g., Button) to its native counterpart (Android AppCompatButton, iOS UIButton, WinUI Button). Each handler exposes a property mapper and command mapper that translate cross-platform properties into native calls. Handlers are decoupled from the control via the IView interface, making them lighter and more testable than Xamarin's renderers.
Microsoft.Maui.Handlers.ButtonHandler.Mapper.AppendToMapping(
"MyCustomization", (handler, view) =>
{
#if ANDROID
handler.PlatformView.SetAllCaps(false);
#endif
});
Real-world example A team removes the default all-caps styling on Android buttons app-wide by appending one line to the ButtonHandler mapper, without subclassing anything.
Common follow-ups: How do you customize a handler? | What is a property mapper?
Handlers Property Mapper Platform Integration
Renderers in Xamarin.Forms were tightly coupled to the control hierarchy and carried significant overhead because each control inherited a full renderer. Handlers are loosely coupled through interfaces (IView/IElement), have a smaller surface area, are easier to unit test, and allow customization via mappers without inheritance. This improves startup time and reduces memory usage.
Real-world example Profiling a migrated app shows faster page load because handlers instantiate less object graph per control than the old renderer pipeline.
Common follow-ups: What is IView? | How do mappers enable customization?
Handlers Renderers Performance
MAUI uses the .NET Generic Host. MauiProgram.CreateMauiApp() builds a MauiAppBuilder where you register the App class via UseMauiApp<App>(), configure fonts, register services in the DI container, and add handlers or libraries. The builder produces a MauiApp that the platform-specific entry points (MainActivity, AppDelegate) bootstrap.
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.ConfigureFonts(fonts =>
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular"));
builder.Services.AddSingleton<IDataService, DataService>();
builder.Services.AddTransient<MainPage>();
return builder.Build();
}
Real-world example A team wires up logging, HTTP clients, and view models in MauiProgram so every page resolves its dependencies from the host container.
Common follow-ups: How is DI configured at startup? | What calls CreateMauiApp?
Dependency Injection Generic Host App Lifecycle
App (Application) is the singleton root of the app and creates the initial Window. A Window represents an OS window/screen host and owns a navigation root (its Page). A Page is a single screen of content. Desktop platforms can open multiple Windows; mobile typically uses one. Application.Windows exposes all open windows.
public partial class App : Application
{
public App() => InitializeComponent();
protected override Window CreateWindow(IActivationState? state)
=> new Window(new AppShell()) { Title = "W3Teacher" };
}
Real-world example A desktop MAUI app opens a second Window for a detached document editor while keeping the main dashboard Window active.
Common follow-ups: How do you open a second window? | What is AppShell?
Multi-window Shell App Lifecycle