.NET MAUI en 2026: Desarrollo Multiplataforma y Preguntas de Entrevista
Tutorial de .NET MAUI para 2026: desarrollo de aplicaciones multiplataforma con .NET 10, handlers, MVVM, HybridWebView. Incluye preguntas de entrevista con respuestas detalladas.

.NET MAUI (Multi-platform App UI) se ha consolidado como un framework multiplataforma de grado producción con .NET 10. Lanzado como una versión Long-Term Support con soporte hasta noviembre de 2028, .NET MAUI 10 se distribuye como workload y paquetes NuGet, ofreciendo mejoras en calidad, rendimiento y nuevas APIs como las optimizaciones de HybridWebView y SafeAreaEdges. Este tutorial cubre la construcción de una aplicación multiplataforma, la arquitectura que hace funcionar a MAUI, y las preguntas de entrevista que los equipos de contratación formulan en 2026.
.NET 10 es una versión Long-Term Support (con soporte hasta noviembre de 2028). MAUI 10 prioriza la calidad y el rendimiento por encima de nuevos controles de UI — convirtiéndola en la versión más estable de MAUI hasta la fecha. Ahora se distribuye como workload de .NET y paquetes NuGet, permitiendo el versionado fijo por proyecto.
Configuración de un Proyecto .NET MAUI 10 desde Cero
El camino más rápido hacia una aplicación MAUI funcional comienza con la CLI de .NET. .NET 10 introduce una plantilla de proyecto actualizada que incluye las configuraciones predeterminadas de .NET Aspire, conectando telemetría y descubrimiento de servicios de forma nativa.
# Instalar el workload MAUI (si no está presente)
dotnet workload install maui
# Crear una nueva aplicación MAUI
dotnet new maui -n CrossPlatformDemo
cd CrossPlatformDemo
# Ejecutar en el emulador Android
dotnet build -t:Run -f net10.0-androidLa estructura de proyecto único consolida el código específico de cada plataforma en una carpeta Platforms/ mientras comparte el resto. El archivo MauiProgram.cs sirve como raíz de composición — aquí es donde se registran los servicios, fuentes y handlers.
using Microsoft.Extensions.Logging;
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
});
// Register services for dependency injection
builder.Services.AddSingleton<IApiService, ApiService>();
builder.Services.AddTransient<MainViewModel>();
#if DEBUG
builder.Logging.AddDebug();
#endif
return builder.Build();
}
}La inyección de dependencias en MAUI sigue el mismo patrón que ASP.NET Core. Los servicios Singleton persisten durante toda la vida de la aplicación, los servicios Transient se crean por cada solicitud, y los servicios Scoped — aunque disponibles — requieren precaución porque MAUI no tiene un concepto de scope integrado como las solicitudes HTTP.
Handlers: La Arquitectura Detrás del Renderizado Multiplataforma
MAUI reemplazó los renderers de Xamarin.Forms con una arquitectura de handlers. Los handlers mapean cada control multiplataforma a su contraparte nativa mediante una capa de abstracción delgada. La diferencia clave: los handlers son sin estado y están desacoplados de la vista virtual, lo que los hace más rápidos y fáciles de personalizar.
using Microsoft.Maui.Handlers;
public class CustomEntryHandler : EntryHandler
{
protected override void ConnectHandler(MauiAppCompatEditText platformView)
{
base.ConnectHandler(platformView);
// Remove the default underline on Android
platformView.SetBackgroundColor(Android.Graphics.Color.Transparent);
}
}
// Register in MauiProgram.cs
builder.ConfigureMauiHandlers(handlers =>
{
handlers.AddHandler<Entry, CustomEntryHandler>();
});En .NET 10, los controles de Entry y Editor en Android pasaron de AppCompatEditText a MauiAppCompatEditText, agregando soporte nativo para el evento SelectionChanged. Los handlers mejorados de CollectionView y CarouselView introducidos en .NET 9 son ahora los predeterminados en iOS y Mac Catalyst, resolviendo problemas de estabilidad que existían desde hace tiempo.
MVVM con CommunityToolkit.Mvvm: Eliminando el Código Repetitivo
El generador de código fuente CommunityToolkit.Mvvm elimina aproximadamente el 80% de la ceremonia MVVM. Sin implementaciones manuales de INotifyPropertyChanged, sin wrappers de comandos — los atributos dirigen la generación de código.
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
public partial class MainViewModel : ObservableObject
{
private readonly IApiService _apiService;
public MainViewModel(IApiService apiService)
{
_apiService = apiService;
}
// Source generator creates the 'Title' property with change notification
[ObservableProperty]
private string _title = string.Empty;
// Source generator creates the 'IsLoading' property
[ObservableProperty]
private bool _isLoading;
// Source generator creates an async ICommand
[RelayCommand]
private async Task LoadDataAsync()
{
IsLoading = true;
try
{
Title = await _apiService.FetchTitleAsync();
}
finally
{
IsLoading = false;
}
}
}El XAML se enlaza directamente a las propiedades y comandos generados:
<!-- MainPage.xaml -->
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:vm="clr-namespace:CrossPlatformDemo.ViewModels"
x:DataType="vm:MainViewModel">
<VerticalStackLayout Padding="20" Spacing="16">
<Label Text="{Binding Title}"
FontSize="24"
HorizontalOptions="Center" />
<Button Text="Load Data"
Command="{Binding LoadDataCommand}"
IsEnabled="{Binding IsLoading, Converter={StaticResource InverseBoolConverter}}" />
<ActivityIndicator IsRunning="{Binding IsLoading}"
IsVisible="{Binding IsLoading}" />
</VerticalStackLayout>
</ContentPage>El atributo x:DataType habilita los bindings compilados, que son más rápidos que los bindings basados en reflexión y producen errores en tiempo de compilación cuando una ruta de binding es incorrecta.
¿Listo para aprobar tus entrevistas de .NET?
Practica con nuestros simuladores interactivos, flashcards y tests técnicos.
HybridWebView en .NET 10: El Puente entre lo Nativo y la Web
HybridWebView permite incrustar contenido web dentro de una aplicación MAUI manteniendo comunicación bidireccional entre C# y JavaScript. .NET 10 agrega tres capacidades: invocación JavaScript de tipo fire-and-forget, eventos de inicialización para configuración específica de la plataforma, e interceptación de solicitudes web.
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
// Initialization event for platform-specific tweaks
hybridWebView.WebViewInitialized += (sender, args) =>
{
// Access the native platform view after initialization
System.Diagnostics.Debug.WriteLine("WebView ready");
};
}
// Call JavaScript from C#
private async void OnCallJsClicked(object sender, EventArgs e)
{
var result = await hybridWebView.InvokeJavaScriptAsync<string>(
"getFormData", // JS function name
HybridSampleContext.Default.String // JSON serialization context
);
await DisplayAlert("Result", result, "OK");
}
// Fire-and-forget: no return type needed (.NET 10)
private async void OnResetClicked(object sender, EventArgs e)
{
await hybridWebView.InvokeJavaScriptAsync("resetForm");
}
}El JavaScript correspondiente recibe las llamadas y puede enviar mensajes de vuelta a C#:
function getFormData() {
return JSON.stringify({
name: document.getElementById('name').value,
email: document.getElementById('email').value
});
}
function resetForm() {
document.getElementById('name').value = '';
document.getElementById('email').value = '';
}Las excepciones JavaScript lanzadas durante InvokeJavaScriptAsync ahora se reenvían automáticamente a .NET como excepciones, eliminando las fallas silenciosas.
SafeAreaEdges: Layouts Precisos en Cada Dispositivo
.NET MAUI 10 introduce la propiedad SafeAreaEdges en Layout, ContentView, ContentPage, Border y ScrollView. La nueva enumeración (None, SoftInput, Container, Default, All) reemplaza el antiguo Page.UseSafeArea específico de iOS con un enfoque multiplataforma.
<!-- Granular safe area control per section -->
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
SafeAreaEdges="All">
<Grid RowDefinitions="Auto,*,Auto">
<!-- Header respects all safe areas -->
<Border Grid.Row="0" SafeAreaEdges="Container">
<Label Text="Header" />
</Border>
<!-- Content scrolls under safe areas -->
<ScrollView Grid.Row="1" SafeAreaEdges="SoftInput">
<VerticalStackLayout Padding="16">
<Entry Placeholder="Type here..." />
</VerticalStackLayout>
</ScrollView>
<!-- Footer avoids home indicator -->
<Border Grid.Row="2" SafeAreaEdges="Container">
<Label Text="Footer" />
</Border>
</Grid>
</ContentPage>SoftInput ajusta el contenido cuando aparece el teclado virtual. Container evita las muescas, los sensores y el indicador de inicio. Estos valores se pueden combinar por control, permitiendo que un encabezado se ubique bajo la barra de estado mientras el área de contenido permanece libre.
Migración de Xamarin.Forms a .NET MAUI
Xamarin.Forms llegó al fin de su soporte en mayo de 2024. La migración a MAUI implica cambios estructurales más allá de un simple reemplazo de namespaces. A continuación se presenta una lista de verificación de migración basada en conversiones de proyectos reales:
Xamarin.Forms no tiene soporte desde mayo de 2024. Las aplicaciones que todavía se ejecutan sobre Xamarin presentan riesgos de seguridad y compatibilidad. .NET MAUI 10 (LTS, con soporte hasta noviembre de 2028) es el objetivo de migración designado.
- Estructura del proyecto — Convertir los proyectos específicos de cada plataforma al modelo de proyecto único de MAUI. Mover el código compartido a la raíz, el código de plataforma bajo
Platforms/. - Namespaces — Reemplazar
Xamarin.FormsconMicrosoft.Maui.ControlsyXamarin.EssentialsconMicrosoft.Maui.Essentials(ahora integrado en MAUI). - Renderers a Handlers — Los renderers personalizados deben ser reescritos como handlers. La API de handlers es más simple pero la lógica de mapeo difiere.
- Inicio — Reemplazar la inicialización en
App.xaml.csconMauiProgram.csusando el patrón builder. - Paquetes NuGet — Muchos paquetes de la era Xamarin tienen equivalentes en MAUI. Verificar la compatibilidad antes de actualizar.
- Inyección de dependencias — MAUI usa
Microsoft.Extensions.DependencyInjectionde forma nativa. Reemplazar cualquier contenedor DI de terceros o llamadas aDependencyService.
El .NET Upgrade Assistant automatiza partes de los pasos 1-2, pero los handlers (paso 3) y los ajustes de lógica de negocio requieren trabajo manual.
Preguntas de Entrevista .NET MAUI Esenciales para 2026
Estas preguntas reflejan lo que los equipos de contratación preguntan en 2026, basándose en el ecosistema actual de .NET 10.
¿En qué se diferencia la arquitectura de handlers de MAUI de los renderers de Xamarin.Forms?
Los renderers en Xamarin.Forms estaban fuertemente acoplados tanto al control multiplataforma como a la vista nativa, creando una dependencia bidireccional. Los handlers en MAUI son mapeadores sin estado: reciben notificaciones de cambio de propiedades y las aplican a la vista nativa mediante un diccionario de mappers. Este desacoplamiento significa que los handlers son más fáciles de probar, extender y reutilizar. Los diccionarios PropertyMapper y CommandMapper reemplazan el patrón de override OnElementPropertyChanged, haciendo que la personalización sea explícita en lugar de estar enterrada en sentencias switch.
¿Cuáles son las trampas de los tiempos de vida de DI específicos de MAUI?
MAUI soporta los tiempos de vida Singleton, Transient y Scoped, pero Scoped se comporta de manera diferente que en ASP.NET Core. No existe un límite de scope natural (como una solicitud HTTP). Un servicio Scoped registrado en MAUI actúa como un Singleton a menos que se creen scopes personalizados manualmente. Errores comunes: registrar un ViewModel como Singleton cuando contiene estado específico de la página (datos obsoletos al navegar), o registrar una conexión de base de datos como Transient (agotamiento del pool de conexiones). La regla general: los ViewModels son Transient, los servicios son Singleton, y Scoped se evita a menos que el ciclo de vida del scope se gestione explícitamente.
Al responder preguntas sobre inyección de dependencias, es importante demostrar comprensión de cómo el ciclo de vida de MAUI difiere del modelo de scope por solicitud de ASP.NET Core. Los entrevistadores buscan conocimiento sobre fugas de memoria y problemas de estado obsoleto específicos de aplicaciones móviles de larga ejecución.
¿Cómo difiere el binding compilado del binding basado en reflexión en MAUI?
Los bindings basados en reflexión resuelven las rutas de propiedades en tiempo de ejecución usando System.Reflection, lo cual es lento y produce errores en tiempo de ejecución ante errores de tipeo. Los bindings compilados, habilitados con x:DataType, resuelven las rutas de binding en tiempo de compilación. El compilador genera código de acceso directo a propiedades, omitiendo la reflexión por completo. Esto mejora el tiempo de inicio, reduce las asignaciones de memoria y detecta errores de binding durante la compilación. En .NET 10, el nuevo generador de código fuente XAML optimiza aún más al compilar XAML en tiempo de compilación en lugar de parsearlo en tiempo de ejecución.
¿Qué estrategias existen para compartir código entre una aplicación MAUI y un backend ASP.NET Core?
El enfoque recomendado utiliza una biblioteca de clases compartida que contiene DTOs, lógica de validación y reglas de negocio. Tanto la aplicación MAUI como el backend ASP.NET Core referencian esta biblioteca. .NET 10 refuerza este patrón con la nueva integración de .NET Aspire para MAUI, que proporciona descubrimiento de servicios y telemetría entre proyectos móviles y de backend. Los contratos compartidos usando generadores de código fuente de System.Text.Json aseguran consistencia en la serialización. La restricción clave: la biblioteca compartida debe apuntar a net10.0 (no a TFMs específicos de plataforma) para mantenerse portable.
¿Cuál es la diferencia entre HybridWebView y BlazorWebView en MAUI?
BlazorWebView aloja una aplicación Blazor completa dentro de la aplicación MAUI. Los componentes Razor se renderizan en una WebView incrustada, pero el runtime de .NET se ejecuta nativamente (no a través de WebAssembly). HybridWebView es más liviano: carga contenido HTML/CSS/JS estático y proporciona interoperabilidad de C# a JavaScript sin la sobrecarga del framework Blazor. La elección depende del caso de uso. BlazorWebView es adecuado para equipos con componentes Blazor existentes que desean reutilización de código. HybridWebView conviene en escenarios donde el contenido web existente (dashboards, mapas, editores) necesita integración nativa sin un framework completo.
Para profundizar en estos conceptos, se pueden practicar más preguntas de entrevista .NET en SharpSkill con ejercicios interactivos.
¡Empieza a practicar!
Pon a prueba tu conocimiento con nuestros simuladores de entrevista y tests técnicos.
Conclusión
- .NET MAUI 10 es una versión LTS (soporte hasta noviembre de 2028) enfocada en estabilidad y rendimiento, no en agregar funcionalidades constantemente — lo que la convierte en una opción confiable para aplicaciones multiplataforma en producción
- La arquitectura de handlers reemplaza los renderers de Xamarin con mapeadores sin estado, mejorando la testabilidad y personalización mediante
PropertyMapperyCommandMapper - Los generadores de código fuente de CommunityToolkit.Mvvm eliminan la mayor parte del código repetitivo MVVM — los atributos
[ObservableProperty]y[RelayCommand]reemplazan las implementaciones manuales deINotifyPropertyChangedy comandos - HybridWebView en .NET 10 agrega llamadas JavaScript fire-and-forget, eventos de inicialización e interceptación de solicitudes para la integración nativa-web
- SafeAreaEdges proporciona control granular y multiplataforma sobre muescas, teclados y barras del sistema, reemplazando el antiguo
UseSafeArealimitado a iOS - La migración desde Xamarin.Forms requiere reescritura de handlers y refactorización del inicio — el .NET Upgrade Assistant maneja los cambios de namespaces pero el trabajo manual sigue siendo necesario para los renderers personalizados
- La preparación para entrevistas debe enfocarse en la arquitectura de handlers vs renderers, las trampas de tiempos de vida de DI en aplicaciones de larga ejecución, bindings compilados y las diferencias entre HybridWebView y BlazorWebView
¡Empieza a practicar!
Pon a prueba tu conocimiento con nuestros simuladores de entrevista y tests técnicos.
Etiquetas
Compartir
Artículos relacionados

Top 25 preguntas de entrevista de ASP.NET Core: middleware, DI y minimal APIs
Las preguntas de entrevista de ASP.NET Core más comunes sobre el pipeline de middleware, los tiempos de vida de la inyección de dependencias y las minimal APIs. Cubre las novedades de .NET 9 y .NET 10 con ejemplos de código.

.NET 9 Blazor: Desarrollo Full-Stack con Blazor United en 2026
.NET 9 Blazor United combina renderizado estático SSR, Server y WebAssembly en un framework full-stack unificado. Tutorial práctico que cubre modos de renderizado, streaming, inyección por constructor y patrones listos para producción.

Entity Framework Core: Optimización del Rendimiento y Buenas Prácticas en 2026
Guía completa de optimización de rendimiento con Entity Framework Core 10 en .NET 10. AsNoTracking, consultas compiladas, actualizaciones por lotes, split queries y LeftJoin.