Xamarin till .NET MAUI: Komplett migreringsguide 2026

Xamarin nådde EOL i maj 2024 – det är dags att migrera. Den här guiden täcker Upgrade Assistant, custom renderers till handlers, DependencyService och CI/CD, med konkreta kodexempel.

Xamarin till .NET MAUI Guide 2026

Xamarin nådde slutet av sin livscykel i maj 2024. Om du fortfarande kör en Xamarin.Forms-app är det inte bara teknisk skuld längre – det är en säkerhetsrisk och ett reellt hot mot din närvaro i App Store och Google Play. Google kräver API-nivå 34 (Android 14) för att publicera uppdateringar, och Apple kräver iOS 17. Båda är utanför vad Xamarin stöder. Så, låt oss gå igenom vad du behöver veta för att flytta din app till .NET MAUI 2026.

Varför du måste migrera nu

Sedan Xamarins end-of-life finns det inga fler säkerhetsuppdateringar, buggfixar eller officiellt stöd från Microsoft. Konsekvenserna är konkreta och eskalerar med varje månad som går:

  • App Store och Google Play: Google kräver API-nivå 34 (Android 14) eller högre för att publicera uppdateringar. Xamarin stöder max Android 13. Apple kräver iOS 17 – Xamarin stöder max iOS 16. Resultat: du kan inte längre uppdatera din app.
  • Säkerhetssårbarheter: Kända säkerhetshål i Xamarin patchas inte längre. Varje dag du väntar ökar riskexponeringen för dina användare.
  • CI/CD-pipelines: Moderna build-agenter i Azure DevOps och GitHub Actions är alltmer inkompatibla med Xamarin-projekt. Byggen börjar misslyckas utan förvarning – ofta vid sämsta möjliga tidpunkt.
  • NuGet-ekosystemet: Allt fler tredjepartsbibliotek har slutat ge ut Xamarin-kompatibla versioner. Ditt paketberoende ruttnar under fötterna.

Att stanna kvar på Xamarin 2026 är inte längre ett teknikbeslut – det är ett affärsriskbeslut.

Vad är .NET MAUI och vad är nytt jämfört med Xamarin?

.NET Multi-platform App UI (.NET MAUI) är den officiella efterföljaren till Xamarin.Forms. Det är ett enhetligt ramverk som låter dig bygga native appar för iOS, Android, Windows och macOS med en enda kodbas – och ett enda projekt istället för ett per plattform.

De viktigaste förbättringarna jämfört med Xamarin.Forms:

  • Single-project-struktur: Istället för separata projekt per plattform samlas allt i ett enda projekt med plattformsspecifika undermappar. Kraftigt minskad lösningskomplexitet.
  • Handler-arkitektur: Ersätter den gamla Renderer-modellen med en snabbare, mer modulär design som eliminerar assembly scanning vid uppstart.
  • Inbyggd dependency injection: DependencyService är borta – ersatt av standard .NET DI som redan är bekant från ASP.NET Core. Äntligen.
  • Native AOT-stöd: Ahead-of-Time-kompilering ger markant snabbare uppstartstider och lägre minnesanvändning på iOS och Android.
  • Windows och macOS: Din kodbas kan nu nå fler plattformar utan extra arbete.

För en djupgående genomgång av prestandafördelarna du uppnår efter migreringen, se vår guide om Native AOT och prestandaoptimering i .NET MAUI 10.

Förberedelser: Vad du ska göra innan du skriver en enda rad kod

Ärligt talat är det här den del de flesta hoppar över – och sedan ångrar sig. En framgångsrik migrering börjar med noggrann planering, inte med att köra Upgrade Assistant direkt.

Inventera din kodbas

Börja med att skapa en tydlig bild av vad du faktiskt migrerar:

  • Räkna antal skärmar och sidor (under 20 = enkel migrering, 20–60 = medium, 60+ = komplex)
  • Lista alla custom renderers – dessa är den mest tidskrävande delen att migrera
  • Identifiera all plattformsspecifik kod i Xamarin.iOS- och Xamarin.Android-projekten
  • Kartlägg alla beroenden av DependencyService
  • Notera alla MessagingCenter-anrop (ersätts av WeakReferenceMessenger i CommunityToolkit)

Granska NuGet-paket tidigt

Kontrollera varje NuGet-paket mot .NET MAUI-kompatibilitet. De vanligaste mappningarna:

  • Xamarin.Forms → Inbyggt i .NET MAUI (Microsoft.Maui.Controls)
  • Xamarin.Essentials → Inbyggt i .NET MAUI (Microsoft.Maui.Essentials)
  • Prism.Forms → Prism.Maui
  • Xamarin.CommunityToolkit → CommunityToolkit.Maui
  • ReactiveUI.XamForms → ReactiveUI.Maui

Sätt prestandareferenspunkter

Mät din nuvarande apps uppstartstid, minnesanvändning och renderingsprestanda med profilingsverktyg innan du börjar. Du behöver dessa siffror för att kvantifiera förbättringen efter migreringen – och (inte minst) för att sälja in migreringen internt.

Skapa en dedikerad Git-branch

Commita ett clean state av din Xamarin-app som startpunkt. Migrering i separata commits ger dig möjlighet att rulla tillbaka specifika delar om problem uppstår.

Migreringsmetod 1: .NET Upgrade Assistant (Rekommenderat för de flesta)

Microsoft erbjuder ett kommandoradsverktyg som automatiserar den mekaniska delen av migreringsarbetet. AI-assisterad tooling hanterar vanligtvis 55–70% av jobbet – vilket är mer än du kanske förväntar dig.

Installera Upgrade Assistant via .NET CLI:

dotnet tool install -g upgrade-assistant

Kör migreringsassistenten på din solution:

upgrade-assistant upgrade YourXamarinApp.sln --entry-point YourXamarinApp

Verktyget hanterar automatiskt:

  • Konverterar projektfiler till SDK-style format
  • Uppdaterar TargetFrameworks till .NET 9 med plattformsspecifika TFMs (net9.0-android, net9.0-ios etc.)
  • Lägger till <UseMaui>true</UseMaui> i projektfilen
  • Ersätter Xamarin.Forms och Xamarin.Essentials med rätt MAUI-paket
  • Uppdaterar namespaces från Xamarin.Forms till Microsoft.Maui.Controls

Viktigt: Upgrade Assistant hanterar projektstrukturen men skriver inte om din arkitektur. Custom renderers och DependencyService-beroenden måste du migrera manuellt.

Migreringsmetod 2: Manuell migrering (Rekommenderat för komplexa appar)

För appar med 60+ skärmar, komplex plattformsspecifik kod eller djupa tredjepartsintegrationer ger manuell migrering mer kontroll. Du skapar ett nytt .NET MAUI-projekt och migrerar kod fil för fil:

dotnet new maui -n YourMauiApp
cd YourMauiApp

Fördelen är att du kan modernisera arkitekturen parallellt med migreringen. Nackdelen är tid – räkna med 4–8 veckor för en medelkomplex app (30–60 skärmar, 10–20 custom renderers). Det är mer, men det är ärligare att säga det rakt ut.

Den viktigaste förändringen: Custom Renderers till Handlers

Bytet från Renderers till Handlers är den enskilt största arkitekturförändringen i .NET MAUI – och den mest tidskrävande migreringsdelen. Det är värt att förstå varför Microsoft bytte arkitektur.

Varför bytte Microsoft arkitektur?

I Xamarin.Forms använde ExportRenderer-attributet assembly scanning vid app-start: ramverket sökte igenom alla refererade bibliotek för att hitta och registrera renderers. Det fungerade, men det var kostsamt och ökade uppstartstiden markant. .NET MAUI:s handler-arkitektur löser detta:

  • Handlers registreras explicit – ingen dyr assembly scanning
  • Decoupled från plattformskontroller via PropertyMapper
  • Global scope – en handler-ändring påverkar alla instanser av en kontroll i hela appen
  • Lägre minnesfotavtryck tack vare minskad wrapper-nesting

Från Xamarin Renderer till .NET MAUI Handler

Här är ett konkret exempel – en custom Entry-kontroll som tar bort bakgrunden på Android:

Xamarin.Forms Renderer:

// CustomEntryRenderer.Android.cs
[assembly: ExportRenderer(typeof(CustomEntry), typeof(CustomEntryRenderer))]
namespace YourApp.Droid
{
    public class CustomEntryRenderer : EntryRenderer
    {
        protected override void OnElementChanged(
            ElementChangedEventArgs<Entry> e)
        {
            base.OnElementChanged(e);
            if (Control != null)
            {
                Control.SetBackgroundColor(
                    Android.Graphics.Color.Transparent);
            }
        }
    }
}

.NET MAUI Handler:

// CustomEntryHandler.cs (delat, plattformskod med #if)
using Microsoft.Maui.Handlers;

public class CustomEntryHandler : EntryHandler
{
    public static new PropertyMapper<IEntry, CustomEntryHandler> Mapper =
        new PropertyMapper<IEntry, CustomEntryHandler>(EntryHandler.Mapper)
        {
            [nameof(IEntry.Background)] = MapBackground
        };

    public CustomEntryHandler() : base(Mapper) { }

    private static void MapBackground(
        CustomEntryHandler handler, IEntry entry)
    {
#if ANDROID
        handler.PlatformView.SetBackgroundColor(
            Android.Graphics.Color.Transparent);
#endif
    }
}

Registrera handleren i MauiProgram.cs:

public static class MauiProgram
{
    public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();
        builder
            .UseMauiApp<App>()
            .ConfigureMauiHandlers(handlers =>
            {
                handlers.AddHandler<CustomEntry, CustomEntryHandler>();
            });

        return builder.Build();
    }
}

Projektstruktur: Från multi-projekt till single-project

I Xamarin.Forms hade du separata projekt för varje plattform, vilket ledde till onödig komplexitet och duplicering:

YourApp.sln
  YourApp/            ← Delad kod (Xamarin.Forms)
  YourApp.Android/    ← Android-specifikt
  YourApp.iOS/        ← iOS-specifikt

I .NET MAUI är allt samlat i ett enda projekt med tydliga plattformsspecifika undermappar:

YourApp.sln
  YourApp/
    Platforms/
      Android/        ← Platform-specifik kod
      iOS/
      Windows/
      MacCatalyst/
    Resources/
      Images/         ← Vektorgrafik skalas automatiskt
      Fonts/
      Raw/
    AppShell.xaml
    App.xaml
    MauiProgram.cs

En stor praktisk fördel som lätt glöms bort: du lägger en enda SVG-bild i Resources/Images/ och MAUI genererar automatiskt alla plattformsspecifika bildstorlekar vid byggtid. Det sparar förvånansvärt mycket tid.

DependencyService till inbyggd .NET Dependency Injection

Xamarins DependencyService ersätts av den välkända .NET DI-containern – bekant för alla som arbetat med ASP.NET Core. Personligen tycker jag det är en av de bästa förändringarna i hela migreringen.

Xamarin.Forms med DependencyService:

// Registrering via attribut (Xamarin)
[assembly: Dependency(typeof(FileService_Android))]
namespace YourApp.Droid
{
    public class FileService_Android : IFileService
    {
        public string GetDocumentsPath() =>
            Environment.GetFolderPath(
                Environment.SpecialFolder.Personal);
    }
}

// Användning - tight coupling, svår att testa
var fileService = DependencyService.Get<IFileService>();

.NET MAUI med inbyggd DI och constructor injection:

// MauiProgram.cs - explicit registrering
builder.Services.AddSingleton<IFileService, FileService>();
builder.Services.AddTransient<MainViewModel>();
builder.Services.AddTransient<MainPage>();

// FileService.cs - plattformsspecifik implementation
public class FileService : IFileService
{
    public string GetDocumentsPath()
    {
#if ANDROID
        return Environment.GetFolderPath(
            Environment.SpecialFolder.Personal);
#elif IOS
        return Environment.GetFolderPath(
            Environment.SpecialFolder.MyDocuments);
#else
        return AppContext.BaseDirectory;
#endif
    }
}

// MainViewModel.cs - constructor injection
public class MainViewModel
{
    private readonly IFileService _fileService;

    public MainViewModel(IFileService fileService)
    {
        _fileService = fileService;
    }
}

Namespace-ändringar att känna till

Xamarins namespace-struktur har förändrats genomgående. Här är de mest frekventa mappningarna (spara den här tabellen, du kommer behöva den):

Xamarin.Forms.NET MAUI
Xamarin.FormsMicrosoft.Maui.Controls
Xamarin.Forms.XamlMicrosoft.Maui.Controls.Xaml
Xamarin.EssentialsMicrosoft.Maui.Essentials
Device.BeginInvokeOnMainThreadMainThread.BeginInvokeOnMainThread
Application.Current.MainPageApplication.Current?.Windows[0].Page

I XAML-filer byter du xmlns-deklarationen på varje sida:

<!-- Xamarin.Forms -->
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">

<!-- .NET MAUI -->
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">

Vanliga problem och lösningar

Problem: Visuella skillnader efter migrering

Handler-arkitekturen ger ibland subtilt annorlunda visuellt utseende på kontroller jämfört med Xamarin.Forms. Standardvärden för padding, typsnitt och border-radius kan skilja sig på specifika enheter och OS-versioner. Lösning: planera för en dedikerad visuell QA-runda på riktiga enheter – inte bara simulatorer – på iOS och Android efter migreringen. Dokumentera förväntade skillnader i förväg.

Problem: Tredjepartsbibliotek saknar MAUI-stöd

Hitta paket utan .NET MAUI-version tidigt i processen. Undersök i tur och ordning: (1) finns en CommunityToolkit.Maui-komponent som löser behovet? (2) finns ett konkurrerande paket med MAUI-stöd? (3) kan du kapsla in funktionaliteten bakom ett eget interface och skriva en tunn implementation?

Problem: CI/CD-pipeline bygger inte

Uppdatera dina build-agenter till .NET 9 SDK och installera MAUI workloads explicit. I GitHub Actions:

- name: Setup .NET 9
  uses: actions/setup-dotnet@v4
  with:
    dotnet-version: '9.0.x'

- name: Install MAUI workloads
  run: dotnet workload install maui android ios

- name: Restore
  run: dotnet restore YourApp.sln

- name: Build Android
  run: dotnet build YourApp.sln -f net9.0-android -c Release

Problem: MessagingCenter är borttagen

Xamarins MessagingCenter är inte längre tillgänglig i .NET MAUI. Ersätt med WeakReferenceMessenger från CommunityToolkit.Mvvm:

// Skicka meddelande
WeakReferenceMessenger.Default.Send(new UserLoggedInMessage(user));

// Ta emot
WeakReferenceMessenger.Default.Register<UserLoggedInMessage>(
    this, (recipient, message) =>
    {
        // Hantera meddelandet
    });

Integration med molntjänster efter migrering

En framgångsrik migration öppnar dörren för moderna backend-integrationer. Med .NET MAUI kan du utan extra arbete koppla din app mot moderna .NET-baserade backend-tjänster. För att ta nästa steg med serviceanslutningar och telemetri, utforska .NET Aspire med .NET MAUI för tjänsteupptäckt och resiliens – ett naturligt nästa steg efter att du landat i MAUI.

Vad du vinner efter migreringen

En framgångsrik migration till .NET MAUI ger mätbara och konkreta fördelar:

  • Snabbare uppstartstid: Handler-arkitekturen och Native AOT ger typiskt 30–40% kortare cold start på iOS och Android.
  • Lägre app-storlek: Single-project med trimning ger normalt 20–25% mindre APK/IPA-storlek.
  • Windows och macOS utan extra kostnad: Samma kodbas kan nu nå fyra plattformar.
  • Modernare tooling: Visual Studio 2022, .NET Hot Reload och XAML Live Preview fungerar sömlöst.
  • App Store och Google Play-kompatibilitet: Du kan återigen publicera uppdateringar utan blockeringar.
  • Framtidssäkrad investering: Microsoft investerar aktivt i .NET MAUI – .NET 10 och framåt bygger vidare på plattformen.

Vanliga frågor om Xamarin till .NET MAUI-migrering

Hur lång tid tar en Xamarin till .NET MAUI-migrering?

Det beror på appens komplexitet. En enkel app med under 20 skärmar och få custom renderers kan migreras på 1–2 veckor. En medelkomplex app (30–60 skärmar, 10–20 renderers) tar typiskt 4–8 veckor med AI-assisterat arbete. Komplexa appar med djup plattformsspecifik kod kan ta 3–6 månader.

Kan jag använda .NET Upgrade Assistant för hela migreringen?

Upgrade Assistant hanterar projektstrukturen, namespace-uppdateringar och NuGet-byte automatiskt – ungefär 55–70% av det mekaniska arbetet. Custom renderers, DependencyService-arkitektur och MessagingCenter måste du migrera manuellt, eftersom det kräver arkitekturbeslut som verktyget inte kan fatta åt dig.

Vad händer om ett NuGet-paket jag använder saknar .NET MAUI-stöd?

Kontrollera om CommunityToolkit.Maui täcker funktionaliteten, leta efter ett konkurrerande paket med MAUI-stöd, eller kapsla in beroendet bakom ett eget interface och skriv en tunn plattformsimplementation. Inventera alltid dina paket tidigt i migreringsprocessen för att undvika blockerare sent i projektet.

Måste jag skriva om alla custom renderers till handlers?

Det finns en kompatibilitetslösning som låter dig behålla gamla renderers temporärt, men det rekommenderas inte långsiktigt. Handlers ger betydande prestandafördelar och är den arkitektur som framtida .NET MAUI-versioner bygger vidare på. Planera att skriva om renderers till handlers som en del av migreringen.

Fungerar min befintliga XAML i .NET MAUI?

Ja, XAML-syntaxen är i stort sett kompatibel men xmlns-deklarationen på varje sida måste uppdateras från http://xamarin.com/schemas/2014/forms till http://schemas.microsoft.com/dotnet/2021/maui. Upgrade Assistant hanterar detta automatiskt. Vissa kontrollnamn och egenskaper kan ha bytt namn – planera för en genomgång efter konverteringen.

Om Författaren Editorial Team

Our team of expert writers and editors.