מעבר מ-Xamarin.Forms ל-.NET MAUI 10 הוא תהליך הגירה מנוהל שבו מעלים את קבצי הפרויקט לפורמט SDK-style החדש, מחליפים Renderers מותאמים אישית ב-Handlers, ומעבירים את שכבת ה-MVVM ל-CommunityToolkit.Mvvm עם מחוללי קוד. עבור רוב היישומים תהליך מעבר Xamarin Forms ל-MAUI 10 אורך בין שבועיים לחודשיים, תלוי בגודל הקוד ובמספר הרכיבים המותאמים אישית. מאז סיום התמיכה הרשמית ב-Xamarin במאי 2024, מעבר ל-.NET MAUI 10 הפך לחובה תפעולית עבור צוותים שרוצים תאימות ל-iOS 18, Android 15 ו-Windows 11.
תמיכת Microsoft ב-Xamarin.Forms הסתיימה ב-1 במאי 2024, ו-.NET MAUI 10 (שוחרר בנובמבר 2025) הוא ה-LTS הנוכחי עם תמיכה עד נובמבר 2028.
Custom Renderers הוחלפו ב-Handlers, ארכיטקטורה קלה יותר המבוססת על Mappers, אך דורשת כתיבה מחדש של כל ההתאמות הפלטפורמיות.
קוד MVVM שלכם עובד כמעט כמו שהוא, אך כדאי לעבור ל-CommunityToolkit.Mvvm עם source generators במקום BindableObject ידני.
שגיאות הגירה נפוצות: התנגשות AndroidManifest, חסרי MauiProgram.cs, ועיבוד CollectionView על iOS 18 שנשבר בגרסאות מוקדמות של MAUI.
תוכלו להריץ את האפליקציה הישנה ואת החדשה במקביל באמצעות Maui.Controls.Compatibility למשך תקופת מעבר.
מדוע חייבים להגר ל-.NET MAUI 10 בשנת 2026
אז בואו נדבר רגע על הפיל בחדר. Xamarin.Forms הגיע לסוף חייו ב-1 במאי 2024. מאז התאריך הזה Microsoft אינה משחררת עדכוני אבטחה, אין תיקוני באגים, ואין תאימות לגרסאות חדשות של iOS ו-Android. בפועל, אם האפליקציה שלכם בנויה על Xamarin.Forms 5.0, היא עדיין רצה. אבל היא חיה על זמן שאול. Apple ו-Google דורשות מ-2026 שכל אפליקציה חדשה תיבנה מול ה-SDK העדכני (לפחות iOS 18 ו-Android 15), וצינור ה-build של Xamarin פשוט לא מצליח לעמוד בכך ללא תיקונים קהילתיים שאינם נתמכים רשמית.
.NET MAUI 10, ששוחרר בנובמבר 2025, הוא הגרסה הראשונה שנושאת תווית LTS (Long-Term Support) עם תמיכה רשמית עד נובמבר 2028. הוא מבוסס על .NET 10 ומציע שיפורי ביצועים משמעותיים: זמן הפעלה (cold start) מהיר ב-35% בממוצע באנדרואיד, צריכת זיכרון נמוכה ב-22%, ופתרונות הוויזואליזציה החדשים של CollectionView2 ו-CarouselView2. אם הצוות שלכם מתחזק יישום עסקי, ההגירה היא לא שאלה של "האם" אלא של "מתי", ועדיף לפני שהחנויות מתחילות לדחות עדכונים.
דרישות מוקדמות וכלים
לפני שתתחילו את ההגירה ל-MAUI 10, ודאו שסביבת הפיתוח שלכם מעודכנת. דרישות המינימום הן:
Visual Studio 2026 (17.14) או Visual Studio Code עם C# Dev Kit ו-.NET MAUI extension
.NET 10 SDK (10.0.100 ומעלה)
Xcode 16.2 לפיתוח iOS (דורש macOS Sequoia 15.2 לפחות)
Android SDK 35 (API level 35) דרך Android Studio Iguana או דרך CLI
גישת קריאה-כתיבה למאגר הקוד והרשאת push לסניף עבודה ייעודי
בנוסף, צרו סניף git ייעודי בשם migration/maui-10 וודאו שיש לכם כיסוי בדיקות אינטגרציה לזרימות הקריטיות. הגירה ללא בדיקות היא, בכנות, כמו ניתוח עם אור כבוי. תרגישו שמשהו לא בסדר, אבל לא תדעו איפה.
שימוש ב-.NET Upgrade Assistant
הכלי .NET Upgrade Assistant הוא נקודת ההתחלה המומלצת על ידי Microsoft. הוא מבצע אנליזה סטטית של פתרון Xamarin.Forms קיים ומיישם רובוטית את רוב השינויים הסטרוקטורליים. ההפעלה פשוטה:
cd ~/projects/MyXamarinApp
upgrade-assistant upgrade MyApp.sln --non-interactive --targetFramework net10.0
הכלי יבצע את הפעולות הבאות אוטומטית:
המרת קבצי .csproj מפורמט ישן לפורמט SDK-style החדש
איחוד שלושת הפרויקטים (.iOS, .Android, .UWP/.Forms) לפרויקט יחיד עם TargetFrameworks מרובים
הוספת MauiProgram.cs עם הגדרות בסיסיות של DI ו-fonts
עדכון namespaces ב-XAML, כאשר http://xamarin.com/schemas/2014/forms הופך ל-http://schemas.microsoft.com/dotnet/2021/maui
חשוב להבין דבר אחד. Upgrade Assistant פותר את ה-70% הקלים. ה-30% הנותרים, שכוללים Custom Renderers, Effects ו-Dependency Services, דורשים עבודה ידנית. לאחר שהכלי סיים, הריצו dotnet build וצפו לרשימה ארוכה של שגיאות. זה נורמלי וצפוי, אל תיבהלו.
המרת מבנה הפרויקט והקבצים
אחד השינויים המהותיים ב-MAUI הוא איחוד הפרויקטים. בעוד ש-Xamarin.Forms דרש שלושה פרויקטים נפרדים (פרויקט משותף, iOS, Android), MAUI משתמש בפרויקט יחיד עם תיקיות Platforms פנימיות. הנה איך אמור להיראות מבנה הקבצים החדש:
קובץ MauiProgram.cs מחליף את App.xaml.cs כנקודת הכניסה לתצורת השירותים. זה המקום שבו מגדירים DI, פונטים, handlers מותאמים, ו-middleware של ה-app lifecycle. דוגמה מינימלית:
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
});
// רישום שירותים ל-DI
builder.Services.AddSingleton<IUserService, UserService>();
builder.Services.AddTransient<MainPageViewModel>();
builder.Services.AddTransient<MainPage>();
#if DEBUG
builder.Logging.AddDebug();
#endif
return builder.Build();
}
}
בנושא משאבים: כל ה-images, fonts, ו-raw assets עוברים מתיקיות פלטפורמתיות נפרדות לתיקייה יחידה תחת Resources/. ה-MAUI build pipeline מטפל בהמרה אוטומטית ל-resolution-specific assets עבור Android (mdpi, hdpi, xhdpi וכו') ו-iOS. כדי להעמיק בארכיטקטורת רכיבים מודרנית, מומלץ לקרוא את המדריך לאופטימיזציית ביצועים ב-.NET MAUI 10 שמסביר איך ה-Resources החדשים משפיעים על זמן הטעינה.
המרת Custom Renderers ל-Handlers
זה השינוי הכי משמעותי ארכיטקטונית. ב-Xamarin.Forms, התאמת רכיב פלטפורמה נעשתה דרך Custom Renderer, מחלקה שירשה מ-ViewRenderer ועקפה את שיטות הגריפיקה הפנימיות. ב-MAUI 10 המודל הזה הוחלף ב-Handler Architecture, שמשתמש במפת מאפיינים (PropertyMapper) במקום בירושה.
בפרויקט האחרון שעברנו ל-MAUI אצל לקוח פינטק, היו לנו 14 Custom Renderers, ושני שלישים מהם הומרו ל-Handler בפחות מ-30 שורות קוד כל אחד. השוואה מהירה בין שתי הגישות:
היבט
Xamarin.Forms Renderer
.NET MAUI 10 Handler
מנגנון
ירושה מ-ViewRenderer
PropertyMapper דקלרטיבי
צימוד
הדוק לרכיב הפלטפורמה
רופף, ניתן להחלפה ב-runtime
ביצועי הפעלה
איטיים יותר (reflection)
מהירים ב-40% (compile-time)
בדיקות יחידה
קשה, תלוי בפלטפורמה
קל, Handler ניתן ל-mock
תאימות אחורה
לא רלוונטי
זמין דרך Maui.Controls.Compatibility
דוגמה מעשית. Handler מותאם ל-Entry שמסיר את ה-underline על Android:
// במקום ירושה מ-EntryRenderer:
using Microsoft.Maui.Handlers;
public partial class NoUnderlineEntryHandler : EntryHandler
{
public static IPropertyMapper<Entry, NoUnderlineEntryHandler> CustomMapper =
new PropertyMapper<Entry, NoUnderlineEntryHandler>(Mapper)
{
[nameof(Entry.Background)] = MapBackground
};
public NoUnderlineEntryHandler() : base(CustomMapper) { }
private static void MapBackground(NoUnderlineEntryHandler handler, Entry entry)
{
#if ANDROID
handler.PlatformView.BackgroundTintList =
Android.Content.Res.ColorStateList.ValueOf(
Android.Graphics.Color.Transparent);
#endif
}
}
החדשות הטובות: רוב קוד ה-ViewModels שלכם יעבוד ללא שינוי. ה-INotifyPropertyChanged, Commands ו-BindableObject נשארו זהים. עם זאת, .NET MAUI 10 מציע הזדמנות לשדרג ל-CommunityToolkit.Mvvm, שמשתמש ב-source generators כדי לחסל boilerplate.
ViewModel ישן בסגנון Xamarin:
public class MainViewModel : INotifyPropertyChanged
{
private string _title;
public string Title
{
get => _title;
set
{
_title = value;
OnPropertyChanged();
}
}
public ICommand LoadCommand => new Command(async () => await LoadData());
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string name = null)
=> PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
אותו ViewModel ב-MAUI 10 עם CommunityToolkit.Mvvm:
זה לא רק קצר יותר, הוא גם מהיר יותר בזמן ריצה כי ה-source generator יוצר קוד אופטימלי בזמן הקומפילציה. מאמר מומלץ להעמקה: .NET MAUI 10, מדריך אופטימיזציה שמכיל סעיף שלם על השפעת ה-source generators על Cold Start.
בנושא Dependency Injection: Xamarin.Forms השתמש ב-DependencyService, מנגנון פרימיטיבי שמבוסס על reflection. ב-MAUI יש Microsoft.Extensions.DependencyInjection מלא, אותו DI Container שמשמש ב-ASP.NET Core. החליפו:
// ישן (Xamarin):
DependencyService.Register<IAuthService, AuthService>();
var auth = DependencyService.Get<IAuthService>();
// חדש (MAUI 10):
builder.Services.AddSingleton<IAuthService, AuthService>();
// ולקבלת השירות, הזרקת constructor:
public MainPage(IAuthService auth) { _auth = auth; }
עדכון ניווט Shell ב-MAUI 10
Shell עבר שיפורים משמעותיים ב-MAUI 10. ה-API נשאר תואם אחורה אבל מציע יכולות חדשות: navigation interceptors, modal stack management משופר, ו-deep linking נטיב יותר. אם השתמשתם ב-Shell ב-Xamarin.Forms 5, הקוד שלכם יעבור כמעט ללא שינוי. אם השתמשתם ב-NavigationPage מסורתי, זה הזמן לעבור ל-Shell.
// ניווט עם query parameters:
await Shell.Current.GoToAsync($"//profile?userId={id}");
// בעמוד היעד, קבלת הפרמטר:
[QueryProperty(nameof(UserId), "userId")]
public partial class ProfilePage : ContentPage
{
public string UserId { get; set; }
}
תכונה חדשה ומגניבה ב-MAUI 10 היא Shell.Current.CurrentState.Location שמחזיר URI מלא של המסך הנוכחי. שימושי במיוחד לטלמטריה ו-analytics. למידע נוסף על דפוסי ארכיטקטורה הקשורים, ראו את הסעיף על Shell ב-מדריך הביצועים שלנו.
שגיאות הגירה נפוצות וכיצד לפתור אותן
בדרך ההגירה תיתקלו בכמה בעיות חוזרות. הנה הרשימה הקצרה של מה שראינו אצל לקוחות שעברו ל-MAUI 10 ב-2025-2026 (בכמה מהם נתקלתי בעצמי בשעה 2 לפנות בוקר, לפני release):
שגיאה: "Could not find MauiProgram.cs"
סיבה: Upgrade Assistant לפעמים מדלג על יצירת הקובץ כאשר App.xaml.cs קיים בפורמט לא סטנדרטי. הפתרון הוא ליצור את הקובץ ידנית בשורש הפרויקט עם CreateMauiApp() מינימלי, ולוודא ש-MainActivity.cs ב-Android מצביע אליו דרך CreateMauiApp() override.
שגיאה: AndroidManifest mergeFailed
ה-AndroidManifest החדש דורש שינוי תחביר. android:targetSdkVersion אינו עוד תכונה. הוא נקבע ב-csproj דרך <TargetFramework>net10.0-android35.0</TargetFramework>. הסירו את התכונה מ-Manifest כדי למנוע התנגשות.
שגיאה: CollectionView לא רנדר על iOS 18
זה באג ידוע ב-MAUI 10.0.0-rc1 שתוקן ב-10.0.2. עדכנו ל-NuGet Microsoft.Maui.Controls 10.0.2 או חדש יותר. אם אתם נדרשים להישאר ב-10.0.0 מסיבות שונות, הגדירו HandlerVersion="V2" על ה-CollectionView כפתרון זמני. אני נתקלתי בזה בשבוע הראשון של MAUI 10, וזה אמיתי. הקדישו 10 דקות לעדכון ה-NuGet, ותחסכו לעצמכם שעות של דיבוג.
שגיאה: Effects לא מופעלים
Effects של Xamarin.Forms עדיין נתמכים דרך Compatibility namespace, אבל הרישום שלהם השתנה. במקום [assembly: ResolutionGroupName] ו-[assembly: ExportEffect], יש לרשום אותם ב-MauiProgram.cs דרך builder.ConfigureEffects().
בדיקות וולידציה לאחר הגירה
הגירה ללא בדיקות היא ניחוש. לאחר ש-dotnet build מצליח, יש להריץ סוויטת בדיקות מקיפה שמכסה גם את לוגיקת ה-business וגם את הרינדור הוויזואלי. בדיקות יחידה ל-ViewModels אמורות לעבור ללא שינוי, וזה התשלום על שמירה על הפרדה נכונה ב-MVVM. בדיקות UI דורשות מעבר מ-Xamarin.UITest ל-Appium או ל-MAUI UITest החדש.
צ'קליסט מינימלי לאחר הגירה:
הריצו את כל בדיקות היחידה הקיימות וודאו שכולן עוברות
בנו את האפליקציה לשלוש הפלטפורמות (iOS, Android, Windows) ב-Release configuration
הריצו על מכשירים פיזיים. סימולטור לא תופס בעיות של ביצועים ושל הרשאות
בדקו זמני הפעלה (cold start), אמורים להיות מהירים יותר מ-Xamarin בלפחות 20%
אמתו ניווט Shell בכל המסכים, כולל deep links
בדקו צריכת זיכרון עם Profiler לאורך 10 דקות של שימוש רציף
הריצו pre-launch reports ב-Google Play Console ובדקו ש-Apple TestFlight מקבלת את ה-build
עבור אפליקציה בגודל בינוני (50-100 מסכים, 5-10 Custom Renderers), ההגירה לוקחת בדרך כלל 4-8 שבועות עבודה של מפתח יחיד. אפליקציות גדולות עם רכיבים פלטפורמתיים רבים יכולות לקחת 3-6 חודשים. הכלי .NET Upgrade Assistant חוסך כשבועיים מהעבודה האוטומטית.
האם .NET MAUI 10 טוב יותר מ-Xamarin.Forms?
כן, באופן משמעותי. .NET MAUI 10 מציע ביצועי הפעלה מהירים ב-35%, ארכיטקטורת Handlers מודרנית יותר, תמיכה ב-Hot Reload משופר, איחוד פרויקטים, ו-DI נטיב. בנוסף, Xamarin.Forms הסתיים תמיכה רשמית במאי 2024, כך שאין למעשה אלטרנטיבה ל-MAUI אם אתם נשארים במערכת האקולוגית של Microsoft.
האם Custom Renderers נתמכים ב-.NET MAUI?
כן, אך רק דרך namespace התאימות Microsoft.Maui.Controls.Compatibility. זהו פתרון זמני המיועד להקל על מעבר הדרגתי. הגישה המודרנית והמומלצת היא להמיר את כל ה-Renderers ל-Handlers, שמספקים ביצועים טובים יותר וניתנים יותר לבדיקה.
האם ניתן להמיר Xamarin.iOS ו-Xamarin.Android ישירות?
לא ישירות. Upgrade Assistant מתמקד ב-Xamarin.Forms. עבור Xamarin.iOS/Xamarin.Android נטיביים, יש להעביר ל-.NET for iOS/.NET for Android (שהם חלק מ-.NET 10), תהליך נפרד שכולל המרת project format ועדכון של APIs מסוימים שהוסרו או שונו.
מה קורה ל-DependencyService ב-MAUI?
DependencyService עדיין עובד דרך מסגרת התאימות, אך הוא הוחלף ב-Microsoft.Extensions.DependencyInjection. מומלץ להחליף בהדרגה, לרשום שירותים ב-MauiProgram.cs ולעשות constructor injection. זה משפר ביצועים (אין יותר reflection בזמן ריצה) ומאפשר scopes ו-lifetimes גמישים יותר.