.NET MAUI di 2026: Panduan Pengembangan Cross-Platform dan Pertanyaan Interview

Panduan .NET MAUI mencakup pengembangan cross-platform dengan .NET 10, handler, MVVM, HybridWebView, dan pertanyaan interview penting tahun 2026.

.NET MAUI cross-platform development tutorial 2026

.NET MAUI (Multi-platform App UI) telah berkembang menjadi framework cross-platform yang siap produksi dengan hadirnya .NET 10. Sebagai rilis Long-Term Support yang didukung hingga November 2028, .NET MAUI 10 hadir sebagai workload dan paket NuGet, menghadirkan peningkatan kualitas, performa, serta API baru seperti peningkatan HybridWebView dan SafeAreaEdges. Panduan ini membahas cara membangun aplikasi cross-platform, arsitektur di balik MAUI, serta pertanyaan interview yang sering diajukan recruiter di tahun 2026.

.NET MAUI 10 LTS

.NET 10 merupakan rilis Long-Term Support (didukung hingga November 2028). MAUI 10 berfokus pada kualitas dan performa dibanding kontrol UI baru, menjadikannya rilis MAUI paling stabil hingga saat ini. Framework ini kini tersedia sebagai workload .NET dan paket NuGet, memungkinkan pinning versi per proyek.

Menyiapkan Proyek .NET MAUI 10 dari Awal

Cara tercepat untuk memiliki aplikasi MAUI yang berjalan dimulai dengan .NET CLI. .NET 10 memperkenalkan template proyek terbaru yang menyertakan service defaults .NET Aspire, menghubungkan telemetri dan service discovery secara otomatis.

bash
# Install the MAUI workload (if not already present)
dotnet workload install maui

# Create a new MAUI app
dotnet new maui -n CrossPlatformDemo
cd CrossPlatformDemo

# Run on Android emulator
dotnet build -t:Run -f net10.0-android

Struktur single-project mengkonsolidasikan kode platform-specific di bawah folder Platforms/ sambil berbagi sisanya. File MauiProgram.cs berfungsi sebagai composition root, tempat pendaftaran service, font, dan handler.

MauiProgram.cscsharp
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();
    }
}

Dependency injection di MAUI mengikuti pola yang sama dengan ASP.NET Core. Service Singleton bertahan selama masa hidup aplikasi, service Transient dibuat per permintaan, dan service Scoped memerlukan kehati-hatian karena MAUI tidak memiliki konsep scope bawaan seperti HTTP request.

Handler: Arsitektur di Balik Rendering Cross-Platform

MAUI menggantikan renderer Xamarin.Forms dengan arsitektur handler. Handler memetakan setiap kontrol cross-platform ke padanan native-nya melalui lapisan abstraksi yang tipis. Perbedaan utama: handler bersifat stateless dan terpisah dari virtual view, membuatnya lebih cepat dan lebih mudah dikustomisasi.

CustomEntryHandler.cscsharp
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>();
});

Di .NET 10, kontrol Entry dan Editor Android beralih dari AppCompatEditText ke MauiAppCompatEditText, menambahkan dukungan native untuk event SelectionChanged. Handler CollectionView dan CarouselView yang ditingkatkan di .NET 9 kini menjadi default di iOS dan Mac Catalyst, menyelesaikan masalah stabilitas yang telah lama ada.

Android 16 Edge-to-Edge: Breaking Change dan Solusi

Android 16 menghapus mekanisme opt-out untuk tampilan edge-to-edge. Aplikasi yang menargetkan API 36 harus menangani system bar insets dengan benar, atau konten akan dirender secara tidak tepat. .NET 10 memperkenalkan breaking change secara diam-diam: di .NET 9, ContentPage menghormati system bar secara default (perilaku Container), tetapi .NET 10 default ke edge-to-edge (None).

Breaking Change di .NET 10

Aplikasi yang migrasi dari .NET 9 ke .NET 10 mungkin melihat konten dirender di bawah status bar atau navigation bar pada Android 15+. Perbaikannya memerlukan pengaturan SafeAreaEdges secara eksplisit untuk mengembalikan perilaku sebelumnya.

Perbaikannya melibatkan penambahan global implicit style ke App.xaml:

xml
<!-- App.xaml -->
<Application xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="CrossPlatformDemo.App">
    <Application.Resources>
        <ResourceDictionary>
            <Style TargetType="ContentPage" ApplyToDerivedTypes="True">
                <Setter Property="SafeAreaEdges" Value="Container" />
            </Style>
        </ResourceDictionary>
    </Application.Resources>
</Application>

Enum SafeAreaEdges menyediakan kontrol granular:

  • None: konten edge-to-edge tanpa padding safe area
  • SoftInput: selalu padding untuk keyboard
  • Container: mengalir di bawah keyboard, tetap di luar bar dan notch
  • Default: perilaku default platform
  • All: mematuhi semua safe area insets

Pendekatan ini menggunakan Window Insets API saat runtime, membuatnya kompatibel dengan Android 16 di mana opt-out level manifest tidak lagi berfungsi.

MVVM dengan CommunityToolkit.Mvvm: Menghilangkan Boilerplate

Source generator CommunityToolkit.Mvvm mengeliminasi sekitar 80% ceremony MVVM. Tidak perlu implementasi INotifyPropertyChanged manual, tidak perlu command wrapper: atribut menggerakkan code generation.

MainViewModel.cscsharp
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;
        }
    }
}

XAML melakukan binding langsung ke property dan command yang dihasilkan:

xml
<!-- 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>

Atribut x:DataType mengaktifkan compiled bindings, yang lebih cepat daripada binding berbasis refleksi dan menghasilkan error saat compile-time ketika binding path salah.

Siap menguasai wawancara .NET Anda?

Berlatih dengan simulator interaktif, flashcards, dan tes teknis kami.

XAML Source Generator di .NET 10

.NET MAUI 10 memperkenalkan XAML source generator yang mengkompilasi XAML saat build time alih-alih mem-parsing saat runtime. Ini meningkatkan performa startup dan menangkap error XAML selama kompilasi.

Untuk mengaktifkan XAML source generation, tambahkan property ke file proyek:

xml
<PropertyGroup>
  <MauiXamlInflator>SourceGen</MauiXamlInflator>
</PropertyGroup>

.NET 10 Preview 5 juga memperkenalkan implicit XML namespaces yang menghilangkan deklarasi xmlns boilerplate. File GlobalXmlns.cs dapat mengagregasi multiple namespaces:

GlobalXmlns.cscsharp
[assembly: XmlnsDefinition(
    "http://schemas.microsoft.com/dotnet/maui/global",
    "MyApp.Views")]
[assembly: XmlnsDefinition(
    "http://schemas.microsoft.com/dotnet/maui/global",
    "MyApp.Controls")]

Dengan setup ini, file XAML menjadi lebih bersih:

xml
<!-- Before -->
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
        xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
        xmlns:controls="clr-namespace:MyApp.Controls"
        x:Class="MyApp.MainPage">
    <controls:TagView />
</ContentPage>

<!-- After (with global xmlns) -->
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/maui/global"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MyApp.MainPage">
    <TagView />
</ContentPage>

HybridWebView di .NET 10: Menjembatani Native dan Web

HybridWebView memungkinkan penyematan konten web di dalam aplikasi MAUI sambil mempertahankan komunikasi dua arah antara C# dan JavaScript. .NET 10 menambahkan tiga kemampuan: pemanggilan JavaScript fire-and-forget, event inisialisasi untuk konfigurasi platform-specific, dan intersepsi web request.

MainPage.xaml.cscsharp
public partial class MainPage : ContentPage
{
    public MainPage()
    {
        InitializeComponent();

        // Initialization event for platform-specific tweaks
        hybridWebView.WebViewInitialized += (sender, args) =>
        {
            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",
            HybridSampleContext.Default.String
        );
        await DisplayAlertAsync("Result", result, "OK");
    }

    // Fire-and-forget: no return type needed (.NET 10)
    private async void OnResetClicked(object sender, EventArgs e)
    {
        await hybridWebView.InvokeJavaScriptAsync("resetForm");
    }
}

Exception JavaScript yang terjadi selama InvokeJavaScriptAsync kini secara otomatis diteruskan ke .NET sebagai exception, menghilangkan kegagalan yang tidak terdeteksi. Intersepsi web request memungkinkan modifikasi header atau menyediakan respons lokal:

csharp
webView.WebResourceRequested += (s, e) =>
{
    if (e.Uri.ToString().Contains("api/secure"))
    {
        e.Handled = true;
        e.SetResponse(200, "OK", "application/json", GetCustomStream());
    }
};

API yang Deprecated dan Jalur Migrasi

.NET MAUI 10 men-deprecate beberapa API. Aplikasi yang menggunakan API ini sebaiknya bermigrasi ke alternatif yang direkomendasikan.

ListView dan cell terkait: ListView, EntryCell, ImageCell, SwitchCell, TextCell, dan ViewCell telah deprecated. Gunakan CollectionView sebagai pengganti, yang memiliki performa dan stabilitas lebih baik dengan handler iOS/Mac Catalyst yang baru.

MessagingCenter: Dijadikan internal di .NET 10. Ganti dengan WeakReferenceMessenger dari CommunityToolkit.Mvvm.

Metode animasi: FadeTo, RotateTo, ScaleTo, dan metode serupa telah deprecated. Gunakan padanan async: FadeToAsync, RotateToAsync, ScaleToAsync.

TableView: Deprecated, diganti dengan CollectionView.

DisplayAlert/DisplayActionSheet: Diganti dengan DisplayAlertAsync dan DisplayActionSheetAsync.

Migrasi dari Xamarin.Forms ke .NET MAUI

Xamarin.Forms mencapai akhir dukungan pada Mei 2024. Migrasi ke MAUI melibatkan perubahan struktural yang lebih dari sekadar penggantian namespace. Berikut checklist migrasi berdasarkan pengalaman konversi proyek nyata:

Xamarin EOL

Xamarin.Forms tidak lagi didukung sejak Mei 2024. Aplikasi yang masih berjalan di Xamarin memiliki risiko keamanan dan kompatibilitas. .NET MAUI 10 (LTS, didukung hingga November 2028) adalah target migrasi yang ditetapkan.

  1. Struktur proyek: Konversi dari proyek platform-specific ke model single-project MAUI. Pindahkan kode shared ke root, kode platform ke Platforms/.
  2. Namespace: Ganti Xamarin.Forms dengan Microsoft.Maui.Controls dan Xamarin.Essentials dengan Microsoft.Maui.Essentials (kini built-in di MAUI).
  3. Renderer ke Handler: Custom renderer harus ditulis ulang sebagai handler. API handler lebih sederhana tetapi logika pemetaannya berbeda.
  4. Startup: Ganti inisialisasi App.xaml.cs dengan MauiProgram.cs menggunakan builder pattern.
  5. Paket NuGet: Banyak paket era Xamarin memiliki padanan MAUI. Verifikasi kompatibilitas sebelum upgrade.
  6. Dependency injection: MAUI menggunakan Microsoft.Extensions.DependencyInjection secara native. Ganti container DI pihak ketiga atau panggilan DependencyService.

.NET Upgrade Assistant mengotomasi sebagian langkah 1-2, tetapi handler (langkah 3) dan penyesuaian business logic memerlukan pekerjaan manual.

Pertanyaan Interview .NET MAUI Teratas untuk 2026

Pertanyaan-pertanyaan ini mencerminkan apa yang ditanyakan tim hiring di tahun 2026, berdasarkan ekosistem .NET 10 saat ini. Untuk persiapan interview C# dan .NET lebih lanjut, lihat panduan lengkap interview .NET.

Bagaimana arsitektur handler MAUI berbeda dari renderer Xamarin.Forms?

Renderer di Xamarin.Forms memiliki coupling ketat dengan kontrol cross-platform dan native view, menciptakan ketergantungan dua arah. Handler di MAUI adalah mapper stateless: mereka menerima notifikasi perubahan property dan menerapkannya ke native view melalui dictionary mapper. Decoupling ini membuat handler lebih mudah diuji, diperluas, dan digunakan kembali. Dictionary PropertyMapper dan CommandMapper menggantikan pola override OnElementPropertyChanged, membuat kustomisasi eksplisit alih-alih tersembunyi dalam pernyataan switch.

Apa saja jebakan DI lifetime yang spesifik untuk MAUI?

MAUI mendukung lifetime Singleton, Transient, dan Scoped, tetapi Scoped berperilaku berbeda dari ASP.NET Core. Tidak ada batas scope alami (seperti HTTP request). Service Scoped yang didaftarkan di MAUI berperilaku seperti Singleton kecuali scope kustom dibuat secara manual. Kesalahan umum: mendaftarkan ViewModel sebagai Singleton ketika menyimpan state spesifik halaman (data basi saat navigasi), atau mendaftarkan koneksi database sebagai Transient (kehabisan connection pool). Aturan umum: ViewModel bersifat Transient, service bersifat Singleton, dan Scoped dihindari kecuali lifecycle scope dikelola secara eksplisit.

Tips Interview

Saat menjawab pertanyaan DI, tunjukkan pemahaman tentang bagaimana lifecycle MAUI berbeda dari model request-scoped ASP.NET Core. Interviewer mencari kesadaran terhadap memory leak dan masalah state basi yang spesifik pada aplikasi mobile yang berjalan lama.

Bagaimana compiled binding berbeda dari binding berbasis refleksi di MAUI?

Binding berbasis refleksi menyelesaikan property path saat runtime menggunakan System.Reflection, yang lambat dan menghasilkan error runtime untuk kesalahan ketik. Compiled binding, yang diaktifkan melalui x:DataType, menyelesaikan binding path saat compile time. Compiler menghasilkan kode akses property langsung, melewati refleksi sepenuhnya. Ini meningkatkan waktu startup, mengurangi alokasi memori, dan menangkap error binding saat build. Di .NET 10, source generator XAML baru lebih mengoptimalkan ini dengan mengkompilasi XAML saat build time alih-alih mem-parsing saat runtime.

Strategi apa yang ada untuk berbagi kode antara aplikasi MAUI dan backend ASP.NET Core?

Pendekatan yang direkomendasikan menggunakan shared class library yang berisi DTO, logika validasi, dan business rules. Baik aplikasi MAUI maupun backend ASP.NET Core mereferensikan library ini. .NET 10 memperkuat pola ini dengan integrasi .NET Aspire untuk MAUI, yang menyediakan service discovery dan telemetri di seluruh proyek mobile dan backend. Shared contract menggunakan source generator System.Text.Json memastikan konsistensi serialisasi. Batasan utama: shared library harus menargetkan net10.0 (bukan TFM platform-specific) agar tetap portable.

Bagaimana HybridWebView berbeda dari BlazorWebView di MAUI?

BlazorWebView menghosting aplikasi Blazor lengkap di dalam aplikasi MAUI. Komponen Razor merender ke WebView yang disematkan, tetapi runtime .NET dieksekusi secara native (bukan melalui WebAssembly). HybridWebView lebih ringan: memuat konten HTML/CSS/JS statis dan menyediakan interop C#-ke-JavaScript tanpa overhead framework Blazor. Pilihan bergantung pada use case. BlazorWebView cocok untuk tim yang memiliki komponen Blazor dan menginginkan code reuse. HybridWebView cocok untuk skenario di mana konten web yang sudah ada (dashboard, peta, editor) memerlukan integrasi native tanpa framework lengkap.

Latih lebih banyak pertanyaan interview .NET di SharpSkill untuk memperkuat konsep-konsep ini dengan latihan interaktif.

Mulai berlatih!

Uji pengetahuan Anda dengan simulator wawancara dan tes teknis kami.

Sumber

Hal yang Perlu Diingat Developer .NET MAUI 10

  • .NET MAUI 10 adalah rilis LTS (dukungan November 2028) yang berfokus pada stabilitas dan performa, menjadikannya pilihan yang andal untuk aplikasi cross-platform produksi
  • Android 16 mewajibkan edge-to-edge: tambahkan SafeAreaEdges="Container" sebagai global style di App.xaml untuk mengembalikan perilaku .NET 9
  • XAML source generator (MauiXamlInflator=SourceGen) mengkompilasi XAML saat build time, meningkatkan performa startup dan menangkap error lebih awal
  • ListView, TableView, dan MessagingCenter telah deprecated: migrasi ke CollectionView dan WeakReferenceMessenger
  • Arsitektur handler menggantikan renderer Xamarin dengan mapper stateless, meningkatkan testability melalui PropertyMapper dan CommandMapper
  • Source generator CommunityToolkit.Mvvm menghilangkan sebagian besar boilerplate MVVM: atribut [ObservableProperty] dan [RelayCommand] menggantikan implementasi manual
  • HybridWebView di .NET 10 menambahkan pemanggilan JavaScript fire-and-forget, event inisialisasi, dan intersepsi request untuk integrasi native-web
  • Persiapan interview sebaiknya fokus pada arsitektur handler vs. renderer, jebakan DI lifetime di aplikasi long-running, compiled binding, dan trade-off HybridWebView vs. BlazorWebView
Tantangan harian

Bisakah kamu menemukan bug di .NET?

Satu potongan kode nyata, satu bug tersembunyi, satu percobaan per hari. Tanpa akun untuk mencoba.

Anthony Fillion-Maillet

Ditulis oleh

Anthony Fillion-Maillet

Pendiri SharpSkill

Developer fullstack selama lebih dari 10 tahun. Ia menjalankan SharpSkill dan bertanggung jawab atas semua yang diterbitkan di sini.

Diperbarui 14 September 2026

Tag

#dotnet
#maui
#cross-platform
#mobile
#interview

Bagikan

Artikel terkait