Миграция мобильного приложения с Xamarin на .NET MAUI
Microsoft прекратила поддержку Xamarin.iOS и Xamarin.Android в мае 2024. Xamarin.Forms получила extended support до конца 2024 года. Это значит: нет обновлений безопасности, нет поддержки новых версий iOS и Android SDK, нет исправления багов. Приложение на Xamarin — это накапливающийся технический долг с конкретной датой окончания.
.NET MAUI — официальный преемник Xamarin.Forms. Архитектурно это эволюция, а не революция. Но «просто обновить NuGet-пакеты» не получится.
Что ломается при миграции
Структура проекта. В Xamarin.Forms три проекта: общий PCL/Shared + iOS head project + Android head project. В MAUI — единый multi-target проект: один .csproj с <TargetFrameworks>net8.0-ios;net8.0-android</TargetFrameworks>. Нативные ресурсы (иконки, шрифты, Assets) переносятся в Resources/ в корне единого проекта. Вся структура AppDelegate.cs, MainActivity.cs пересобирается.
Namespace-ы и API. Xamarin.Forms → Microsoft.Maui. Это касается каждого using-а в проекте. Звучит как find & replace, но часть классов переименована: Device.BeginInvokeOnMainThread → MainThread.BeginInvokeOnMainThread, Application.Current.MainPage → Application.Current?.Windows[0].Page. Renderers заменены на Handlers — принципиально другая модель кастомизации нативных контролов.
Renderers → Handlers. Это самое болезненное. В Xamarin.Forms кастомный рендерер для Entry — это класс, наследующий EntryRenderer, переопределяющий OnElementChanged. В MAUI Handler — это маппинг свойств через PropertyMapper и CommandMapper. Каждый кастомный рендерер нужно переписать. Если в проекте 5–10 кастомных рендереров — это серьёзный объём работы.
Зависимости и плагины. Часть Xamarin-плагинов (особенно из Xamarin.Essentials, который теперь встроен в MAUI) просто исчезла или была переименована. Сторонние плагины — проверяем на NuGet совместимость с net8.0-ios / net8.0-android. Плагины, которые не обновились до MAUI, нужно заменять альтернативами или писать свои.
Как проводим миграцию
Аудит зависимостей — первый и самый важный шаг. Собираем полный список NuGet-пакетов, проверяем каждый на MAUI-совместимость. Для Xamarin.Essentials зависимостей — хорошая новость: большинство API встроено в MAUI нативно. Для кастомных рендереров составляем список с оценкой трудоёмкости переписывания на Handlers.
Upgrade Assistant. Microsoft выпустила dotnet-maui-check и .NET Upgrade Assistant с поддержкой Xamarin → MAUI. Инструмент делает часть механической работы: обновляет .csproj, меняет target frameworks, переносит ресурсы. Но это ~30–40% работы. Остальное — ручная правка.
Shell navigation. Если проект использовал Xamarin.Forms Shell — это хорошая новость: MAUI Shell совместим концептуально. AppShell.xaml с <TabBar>, <FlyoutItem>, route-регистрация через Routing.RegisterRoute — переезжает с минимальными изменениями.
Dependency Injection. В Xamarin.Forms DI не был встроен — использовали Autofac, DryIoc, TinyIoC. MAUI имеет встроенный MauiAppBuilder с Microsoft.Extensions.DependencyInjection. Это стандартный .NET DI, хорошо знакомый разработчикам ASP.NET. Регистрация сервисов переносится в MauiProgram.cs.
Тестирование. MAUI поддерживает xUnit и NUnit для unit-тестов. Для UI-тестирования — Appium с dotnet-appium-driver или Xamarin.UITest-совместимые подходы через MAUI UI Testing. Покрытие бизнес-логики тестами до миграции — страховка от регрессий.
После миграции обязательны: ручное тестирование на физических устройствах iOS и Android (эмулятора недостаточно для проверки нативного поведения), прогон через TestFlight и Firebase App Distribution до релиза.
Сроки
| Размер проекта | Кастомные рендереры | Ориентир |
|---|---|---|
| До 20 экранов | Нет / 1–3 | 3–5 недель |
| 20–50 экранов | 3–10 | 6–10 недель |
| 50+ экранов | 10+ | 12+ недель |
Стоимость рассчитывается после аудита проекта: анализа .csproj, списка NuGet-зависимостей и количества кастомных рендереров.







