.NET MAUI 11 فقط CoreCLR؛ راهنمای مهاجرت از Mono و تست Preview 6

.NET MAUI 11 فقط CoreCLR؛ راهنمای مهاجرت از Mono و تست Preview 6

در .NET 11 Preview 6 مسیر انتخاب Mono برای اپ های موبایل .NET MAUI حذف شده و CoreCLR تنها Runtime برای Android، iOS و Mac Catalyst است. اگر پروژه MAUI Production دارید، این تغییر را نباید تا GA نوامبر رها کنید؛ الان باید Startup، Package Size، Hot Reload، Reflection و کتابخانه های Native را روی Preview 6 اندازه بگیرید تا مشکل قبل از Release نهایی دیده شود.

چه چیزی در .NET 11 Preview 6 عوض شده؟

در Previewهای قبلی CoreCLR مسیر مهاجرت بود؛ اکنون مسیر جایگزین Mono دیگر expose نمی شود. Targetهای `net11.0-android`، `net11.0-ios` و `net11.0-maccatalyst` روی CoreCLR اجرا می شوند و Property قدیمی انتخاب Mono حذف شده است. از دید تیم محصول، این یعنی «بعداً با یک Switch برمی گردیم» دیگر استراتژی مناسبی نیست. باید Compatibility واقعی اپ با Runtime جدید را بسنجید و اگر Blocker دارید، قبل از GA گزارش کنید.

مزیت معماری این است که Mobile همان Runtime اصلی ASP.NET Core، Cloud Service و Desktop .NET را به اشتراک می گذارد. این همگرایی می تواند Diagnostics، Runtime behavior و سرمایه گذاری Performance را یکپارچه تر کند. اما نتیجه برای هر App یکسان نیست؛ Binding Native، Reflection، Dynamic Code و Libraryهای قدیمی ممکن است assumptions خاص Mono داشته باشند. به همین دلیل Microsoft صریحاً از توسعه دهندگان خواسته Preview 6 را روی App واقعی اجرا کنند و عدد Startup/Size و Repro مشکل را گزارش دهند.

Performance؛ به Benchmark رسمی تعمیم ندهید

Microsoft می گوید iOS و Mac Catalyst عموماً از Mono سریع ترند و Android از نظر Startup و App Size در محدوده 10 درصد Mono قرار دارد. این جمله Guarantee برای پروژه شما نیست. App MAUI می تواند Shell ساده، UI گرافیکی سنگین، Binding زیاد، SQLite، BLE یا SDK شخص ثالث داشته باشد. هرکدام Startup و Memory را متفاوت می کنند. بنابراین Baseline .NET 10 را روی همان Device، Build Configuration و Dataset ثبت کنید و سپس Preview 6 را مقایسه کنید.

شاخصروش اندازه گیریخطای رایج
Cold startupچند اجرای بعد از force-stop روی دستگاه واقعیمقایسه Emulator با Device
Warm startupاجرای تکراری با شرایط ثابتمخلوط کردن Cache state
Package sizeAPK/AAB و IPA نهایی Releaseمقایسه Debug با Release
Memoryسناریوی ثابت navigation/dataقضاوت از یک Snapshot
UI responsivenessinteraction و frame timingاتکا به حس دستی بدون trace

نتیجه را با Median و Range ثبت کنید، نه فقط بهترین اجرا. اگر Android 8 درصد کندتر اما Package کوچک تر و Diagnostics بهتر شد، تصمیم محصول باید Trade-off را ببیند. اگر Regression بزرگ دارید، Repro کوچک بسازید و با Device/OS/Architecture گزارش کنید. Preview دقیقاً برای همین بازخورد وجود دارد.

Diagnostics و Hot Reload؛ چه چیزی آماده است؟

Debugging روی Visual Studio و Visual Studio Code کار می کند و Hot Reload هم در IDE و `dotnet watch` پشتیبانی می شود؛ با این حال Microsoft گفته برخی سناریوهای XAML Hot Reload و مسیرهای iOS هنوز در حال تکمیل اند. پس شکست Hot Reload را فوراً به Runtime Regression Production تعبیر نکنید. Development workflow و Runtime app behavior دو Track جدا هستند و باید جدا ثبت شوند.

خبر مهم تر برای تیم Performance این است که `dotnet-trace` و `dotnet-counters` اکنون روی Mobile App قابل استفاده اند. این همگرایی امکان می دهد الگوهای آشنای Server diagnostics را روی Device ببرید. برای مثال به جای حدس درباره Memory spike هنگام Navigation، Counter و Trace بگیرید و Eventهای GC/JIT را بررسی کنید. Instrumentation استاندارد باعث می شود گزارش Bug از «کند است» به Trace قابل تحلیل تبدیل شود.

dotnet workload install maui
# سپس پروژه را با target net11.0-android / ios / maccatalyst در Release بسازید

دستور بالا همان نقطه شروع رسمی برای نصب workload است؛ بعد از آن Test باید روی Release build و دستگاه واقعی انجام شود. Debug build به دلیل instrumentation و رفتار متفاوت compiler/runtime معیار خوبی برای تصمیم Performance نیست.

Library، Reflection و Dynamic Code؛ نقاط حساس

Microsoft در چک لیست خود به طور مشخص توصیه کرده Libraryهای شخص ثالث، خصوصاً مواردی که Reflection یا Dynamic Code Generation دارند، بررسی شوند. دلیل عملی واضح است: چنین Libraryهایی بیشتر به جزئیات Runtime، trimming و code generation وابسته اند. SDKهای Analytics، ORM، Serialization سفارشی، Dependency Injection پیشرفته، Plugin systems و Bindingهای Native را جداگانه فهرست کنید. فقط بازشدن صفحه اول اپ نشان نمی دهد مسیر کم استفاده در Setting یا Payment سالم است.

یک Compatibility Matrix بسازید که برای هر Dependency شامل Version، Maintainer status، Native asset، Reflection usage و نتیجه تست باشد. اگر Package روی Preview 6 مشکل دارد، قبل از Fork داخلی Issue upstream باز کنید. Fork آخرین گزینه است چون پس از GA Maintenance burden می سازد. اگر Reflection به علت trimming مشکل دارد، annotation یا source-generated alternative را بررسی کنید؛ این تغییر هم به CoreCLR و هم به NativeAOT آینده کمک می کند.

پلن تست روی دستگاه واقعی

  1. پروژه را برای targetهای net11 موبایل Build و Publish کنید.
  2. Cold/Warm startup را با .NET 10 baseline روی همان دستگاه اندازه بگیرید.
  3. APK/AAB یا IPA نهایی را مقایسه کنید.
  4. تمام flowهای Navigation، Data loading و Platform integration را اجرا کنید.
  5. Hot Reload را در workflow روزانه تست و مشکل Tooling را جدا ثبت کنید.
  6. Libraryهای Reflection/Dynamic code و Native SDKها را با سناریوی واقعی اجرا کنید.
  7. Trace و Counter را هنگام کندی یا Memory spike ذخیره کنید.

برای پروژه چندپلتفرمی، یک نتیجه Android را به iOS تعمیم ندهید. Runtime مشترک است اما AOT، Native interop، linker و platform API متفاوت اند. حداقل یک Device واقعی از Platformهای اصلی محصول لازم است. اگر Device Farm دارید، Smoke Test خودکار را روی Preview branch اضافه کنید؛ اما Gesture، Camera، BLE و برخی Native interactionها هنوز Test دستی هدفمند می خواهند.

NativeAOT روی Android؛ الان چه معنایی دارد؟

Microsoft می گوید Foundationهای NativeAOT روی Android در حال Landing هستند و Trimmable Type Map برای Android interop در NativeAOT build به طور پیش فرض فعال است. این خبر را نباید به «همه MAUI Appها الان NativeAOT آماده اند» ترجمه کرد. ارزش فعلی برای تیم معماری این است که Dependencyهای ناسازگار با trimming، reflection-heavy و dynamic code را زودتر شناسایی کند. هرچه اپ به Metadata runtime و code generation کمتر وابسته باشد، گزینه های Deployment آینده بازتر می مانند.

اگر NativeAOT هدف شما نیست هم trimming hygiene سود دارد: App size، startup و predictability بهتر می تواند حاصل شود. ولی optimization را قبل از correctness نگذارید. اول Preview 6 را بدون Refactor بزرگ سبز کنید، بعد experiment NativeAOT/trimming را در Branch جدا انجام دهید. این تفکیک مانع می شود Regression Runtime و Optimization با هم قاطی شوند.

Blazor WebAssembly چه می شود؟

این تغییر مخصوص .NET MAUI Mobile targets است. Microsoft صریحاً گفته Blazor WebAssembly تحت تأثیر نیست و در .NET 11 همچنان Mono را استفاده می کند. اگر MAUI Blazor Hybrid دارید، باید بخش Native host و WebView integration را با Context دقیق بررسی کنید؛ جمله «Blazor از Mono استفاده می کند» به این معنی نیست که کل MAUI host شما مسیر قبلی را دارد. Runtime هر بخش را در معماری خود مشخص کنید تا تیم در Debugging دچار سوءبرداشت نشود.

برای Shared codebase، تست Business library روی CoreCLR و WASM هر دو لازم است اگر واقعاً هر دو target را پشتیبانی می کنید. API availability، reflection و threading behavior می تواند متفاوت باشد. Multi-targeting را در CI واضح نگه دارید و Failure را با Target Framework در نام Job گزارش کنید.

پرسش های متداول

آیا در .NET 11 MAUI هنوز می توان Mono را انتخاب کرد؟

در Preview 6، مسیر جداگانه Mono برای Android، iOS و Mac Catalyst حذف شده و CoreCLR تنها Runtime MAUI Mobile است.

آیا Blazor WebAssembly هم به CoreCLR می رود؟

خیر. Microsoft گفته Blazor WebAssembly در .NET 11 همچنان Mono را استفاده می کند.

Performance Android بهتر می شود؟

Microsoft می گوید Android در Startup و App Size در محدوده 10 درصد Mono است؛ نتیجه اپ خودتان باید Benchmark شود.

چه Libraryهایی را اول تست کنیم؟

Libraryهای دارای Reflection، Dynamic Code Generation، Native interop و SDKهای Platform-specific اولویت بالاتری دارند.

چطور مشکل Performance را گزارش کنیم؟

با Device/OS/App type، Package size، startup timing و در صورت امکان Repro و Trace؛ داده قابل تکرار از توصیف کلی ارزشمندتر است.

منبع اصلی و جمع بندی

وضعیت Runtime، Performance اولیه، Hot Reload، Diagnostics و چک لیست تست از مطلب رسمی .NET Blog استخراج شده اند. توصیه عملی برای تیم MAUI این است که Preview را فقط در نمونه Hello World امتحان نکند؛ همان App واقعی با Dependencyهای واقعی باید قبل از GA روی CoreCLR اندازه گیری شود.

چک لیست Release Manager

  • Baseline .NET 10 روی Device واقعی ثبت شده است.
  • Build Release برای همه targetهای اصلی موفق است.
  • Startup، Size، Memory و flowهای کلیدی مقایسه شده اند.
  • Dependencyهای Reflection/Native در Matrix ثبت شده اند.
  • مشکل Hot Reload از Runtime bug جدا شده است.
  • Trace برای Regressionهای جدی نگهداری می شود.
  • Rollback و branch strategy تا GA روشن است.
  • NativeAOT experiment از migration correctness جدا نگه داشته شده است.

از Preview Test تا تصمیم GA یک مسیر Rollout تعریف کنید

تست Preview زمانی ارزش دارد که خروجی آن به تصمیم Release تبدیل شود. یک Branch یا CI lane مخصوص .NET 11 بسازید که هر شب App واقعی را Build کند و Smoke Testهای اصلی را اجرا کند. Regressionها را با Label مشخص به سه گروه Runtime، Tooling و Dependency تقسیم کنید. این دسته بندی مهم است؛ مشکل Debugger یا Hot Reload نباید با Crash نسخه Release یکی تلقی شود. هر هفته وضعیت Blockerها را مرور کنید و برای هرکدام Owner، Repro و نسخه ای که مشکل در آن دیده شده ثبت کنید. وقتی RC/GA نزدیک می شود، این تاریخچه نشان می دهد ریسک واقعی کجاست و کدام مشکل قبلاً رفع شده است.

برای Rollout Production پس از GA نیز Big Bang لازم نیست. اگر معماری انتشار شما اجازه می دهد، نسخه .NET 11 را ابتدا در کانال Internal یا درصد محدودی از کاربران منتشر کنید و Crash-free session، startup و خطاهای Native را با Baseline قبلی مقایسه کنید. اگر Telemetry محصول چنین Breakdownی ندارد، پیش از مهاجرت آن را اضافه کنید؛ بعد از Rollout دیگر برای ساخت Baseline دیر است. معیار پذیرش را قبل از انتشار بنویسید، مثلاً «Crash rate نباید از محدوده تاریخی تیم خارج شود»؛ عدد دقیق باید از داده واقعی خود محصول بیاید، نه Benchmark عمومی.

Dependencyهای حساس را بر اساس نوع ریسک اولویت بندی کنید

همه Packageها ارزش تست یکسان ندارند. Library خالصی که فقط Collection و HTTP abstraction دارد معمولاً ریسک کمتری از SDK پرداخت، Camera، BLE، Maps یا Binding Native دارد. اولویت دوم Packageهایی هستند که Runtime code generation، dynamic proxy، Reflection گسترده یا Assembly scanning انجام می دهند. برای هر مورد یک سناریوی واقعی تعریف کنید؛ مثلاً برای SDK پرداخت فقط Initialize شدن کافی نیست و باید مسیر callback، background resume و error handling نیز تست شود. این روش زمان محدود Preview را روی جاهایی متمرکز می کند که احتمال Regression و هزینه شکست بیشتر است.

اگر یک Dependency Blocker پیدا شد، سه گزینه را جدا ارزیابی کنید: ارتقای Package، تغییر Configuration یا تعویض Dependency. Fork داخلی را فقط وقتی انتخاب کنید که Owner و برنامه خروج از Fork دارید. همچنین مشکل را با Repro کوچک به Maintainer گزارش کنید؛ پروژه کامل MAUI با ده ها SDK تشخیص را کند می کند. هدف Preview 6 این است که این Blockerها قبل از GA آشکار شوند تا Maintainer و تیم شما زمان اصلاح داشته باشند، نه اینکه روز مهاجرت Production تازه کشف شوند.

مطالب پیشنهادی

Copilot Billing Preview در 3 اوت 2026 بازنشسته می شود؛ راهنمای مهاجرت

Copilot Billing Preview در 3 اوت 2026 بازنشسته می شود؛ راهنمای مهاجرت

راهنمای مهاجرت قبل از بازنشستگی Copilot Billing Preview در 3 اوت 2026؛ AI usage، Budget، گزارش مصرف، Billing API و کنترل FinOps برای تیم ها.

Python 3.15 در آستانه RC؛ قبل از 3.15.0rc1 چه چیزهایی را تست کنیم؟

Python 3.15 در آستانه RC؛ قبل از 3.15.0rc1 چه چیزهایی را تست کنیم؟

راهنمای آمادگی برای Python 3.15.0rc1 در 4 اوت 2026؛ تست CI، Wheel و ABI، Encoding، Dependencyها و برنامه مهاجرت کم ریسک برای Production تیم ها.

قوانین جدید Chrome Web Store از 1 اوت 2026؛ چک لیست Extensionها

قوانین جدید Chrome Web Store از 1 اوت 2026؛ چک لیست Extensionها

چک لیست عملی قوانین جدید Chrome Web Store که از 1 اوت 2026 اجرا می شوند؛ Limited Use، Disclosure داده، AI Guardrails و Prediction Market برای Extensionها.

آپدیت امنیتی Next.js ژوئیه 2026؛ 9 آسیب پذیری و نسخه امن

آپدیت امنیتی Next.js ژوئیه 2026؛ 9 آسیب پذیری و نسخه امن

راهنمای عملی آپدیت امنیتی Next.js ژوئیه 2026؛ نسخه های امن 16.2.11 و 15.5.21، تحلیل ریسک SSRF و Server Actions و چک لیست ارتقای Production برای تیم ها.