Skip to content

Build1 publisher3 min readPublished

A practitioner guide moves large Xamarin apps to .NET MAUI one workflow at a time

Microsoft's Upgrade Assistant belongs inside a phased plan for 200-screen Xamarin apps moving to .NET MAUI, according to a dev.to migration guide. Releases keep shipping under that plan, but each feature added during the move needs both a Xamarin and a MAUI screen.

The Engineer · Build desk

Illustration accompanying A practitioner guide moves large Xamarin apps to .NET MAUI one workflow at a time

What happened

  • A dev.to migration guide says Microsoft's Upgrade Assistant handles many project and namespace transformations but should be treated as an accelerator, with manual work still expected.
  • The guide calls changing the TargetFramework and fixing whatever breaks a common mistake that, on large apps, yields a huge error list before the real risks are understood.
  • It makes a dependency and feature map the first deliverable, covering Xamarin-specific NuGet packages, custom renderers, native code, offline sync and app signing.
  • A 200-screen app, the guide says, should be split into units such as Authentication, Orders and Offline, each carrying its own migration status.
  • It advises against freezing development: new business logic goes into a shared modern layer, Xamarin UI is temporary and MAUI UI is the preferred implementation.

Compiled by The EngineerSomething wrong?How this is made

Why it matters

  • cost Every feature shipped while both apps are live needs a Xamarin screen and a MAUI screen, so never pausing releases means duplicated UI work.
  • decision Sponsors have to accept an inventory as the first milestone, so early progress shows up as a risk map before any MAUI build compiles.
  • constraint Code review has to keep Xamarin statics such as Application.Current out of new business logic for the whole migration, or the shared layer ends up tied to Xamarin again.
  • exposure Estimates built from Upgrade Assistant's output cover the edits the guide rates as rarely hard, leaving renderer and native-code work outside the count.

Changing `<TargetFramework>` is a one-line edit. On a large Xamarin app it moves the whole project to the new platform at once, and the breakage comes back as a single list [4]. The post objects to the order in which problems show up, and it accepts the shortcut for small apps [4]. A compiler reports errors by file and line. File order is a poor guide to which screen takes the payments.

According to the post, namespace replacement and .csproj conversion are rarely the hard part [2]. The hard part is years of assumptions built into third-party libraries, native platform APIs, custom renderers, background processing, authentication, local databases and CI/CD [2]. Upgrade Assistant performs many of the project and namespace transformations [3]. So the tool automates the category of work the post rates as rarely difficult [1].

Some of the inventory questions matter because the answers never reach a compiler. How the app is signed and distributed is on the post's list, and so is which production workflows cannot fail [5].

The best engineering in the post is its rule for new code written during the migration. Its example removes a reference to `Xamarin.Forms.Application.Current` from an `OrderService` and injects an `IOrderRepository` through the constructor, so both generations of the app can consume the same class [9]. Because `Application.Current` belongs to one UI runtime, a service that reads it is tied to that runtime, while a service that takes `IOrderRepository` in its constructor depends only on the interface. The author wrote that this is "one of the most effective ways to prevent the migration from becoming a moving target" [13].

Under the post's routing rule [8], every feature shipped during the migration has two UI implementations [2]. The alternative, freezing development for months, is the one the post rules out [8].

Platform code gets the same treatment. An `IDeviceService` exposing `GetDeviceIdAsync` and `IsNetworkAvailableAsync` gets a `XamarinDeviceService` and a `MauiDeviceService`, and the calling code does not know which one it holds [10]. The post lists ten areas where this helps, among them secure storage, connectivity and background processing [3]. It restricts the abstractions to places where migration or platform differences are expected [11]. In my view that limit is correct, because both apps have to keep every interface in step.

The post does not say how many migrations its advice comes from or how long they took. It also leaves "large" undefined. The 200-screen app is an illustration [6], and a status line such as "Authentication and customer workflows are migrated; offline synchronization and notifications remain" is its example of reporting by unit [7]. For the phased method to beat the one-line edit, I'd expect an app to need two things. It must carry enough Xamarin-only packages, native code and renderers that the error list stops working as a queue. And its release schedule must be unable to pause. Custom renderers are the first thing to count. The post names them as frequently one of the biggest sources of migration effort [12].

What to watch

  • Whether Microsoft's Upgrade Assistant extends its automation beyond project and namespace transformations into renderer or native-code conversion.
  • Detailed guidance on converting custom renderers, the item the guide ranks among the largest sources of migration effort.
  • Case reports with screen counts and durations from teams that ran the phased plan on a production Xamarin app.
Loading claim ledger
Loading source directory links
Loading share composer
Loading topic controls
Loading related stories