Mobilizing Existing .NET Apps
Since the first release of the .NET Framework in 2002, developers have been building large-scale apps with client-server architectures. These apps frequently adopt a layered approach, with business logic to solve diverse and complex problems, accessed via desktop or web front-ends.
Today, C# and .NET are available across a diverse set of platforms in addition to Windows, including Android and iOS with Xamarin, but also wearables like Apple Watch and Android Wear, consumer electronics via Samsung Tizen, and even HoloLens.
In this blog post, I’ll show how to port business logic from WPF and build a phone- and tablet-friendly mobile app for Android, iOS, and UWP. Existing C# code can often be re-used with minimal changes, and the user interfaces can be built using Xamarin.Forms XAML to run across platforms.
Porting a Desktop app with a Mobile Mindset
Mobile apps, unlike desktop or server apps, run on limited resources and have the least user attention span. Although this post focuses mainly on porting the existing code, you should also consider changes to the app architecture or user interface to work better on phones and tablets. A good place to start is our mobile development principles.
Almost any .NET codebase, including Windows Forms, WPF, ASP.NET, and Silverlight, has sharable code that can be ported to Xamarin.iOS, Xamarin.Android and UWP projects. By moving the shared code that is platform agnostic to a .NET Standard Library (or a Shared Project) you can easily reference them in mobile projects.
For this example, I am mobilizing an Expenses sample written a few years ago for a cloud-enabled WPF app demo. The functionality works great on mobile, as you can see here:
The original Expenses app is a thick client written for desktop in WPF. The app helps users manage their charges, create expense reports, and allows submitting for manager approvals. It connects to a WCF backend and SQL Server for data storage, and looks like this:
The following sections detail how the legacy app code was analyzed, re-used, and adapted for mobile deployment. You can download the original code and new mobile solution from my GitHub repo.
Analyze code for Mobilization
In general, any non-platform dependent code i.e. your Business Layer, Data Layer, Data Access Layer, Service Access Layer, etc. can be shared across all platforms. To help you identify what code is sharable, use the .NET Portability Analyzer tool. The .NET Portability Analyzer provides you with a detailed report on how portable your program is across .NET platforms by analyzing assemblies. The Portability Analyzer is offered as a Visual Studio Extension and as a console app. Once you install this extension, be sure to check the platforms that you want to analyze in the settings and then right click on the project you want to analyze and click “Analyze Project Portability”
It will generate a report like the one below from the Expenses WPF app.
The above shown consolidated report has the analysis of two libraries – Expenses.WPF and Expenses.Data. From the report, apparently, Expenses.Data (data layer) is 100% shareable across all platforms and as expected Expenses.WPF is about 80% shareable. These reports are available on my GitHub repo – please refer the detailed sheet within the workbook to understand the libraries that aren’t shareable.
Porting WCF backend to Azure Mobile Apps
I could retain the WCF backend as-is and host it in the cloud for mobile apps to access. However, I decided to port this to Azure Mobile Apps to take advantage of offline sync support that is an essential feature in creating excellent mobile user experiences. In a mobile world, devices are always moving, connectivity varies, and network outages happen. Apps need to be intelligent by falling back on locally stored data and transferring the data on demand when a better network connection is established with the server. Luckily, Azure Mobile Apps provides a simple API for developers through its SDK to support both online and offline scenarios for data storage, including automatically syncing data between a device and server.
The project MyExpenses.MobileAppService has controllers that inherit from TableController that provides a RESTful endpoint and nicely abstracts away the code that supports offline data sync.
Porting the WPF client app to Xamarin.Forms
Xamarin.Forms is a cross-platform UI toolkit that helps you create native user interfaces that can be shared across iOS, Android, and Universal Windows Platform apps. Since the UI is rendered using the native controls of the target platform, Xamarin.Forms retains the appropriate look and feel on every platform. Just like in WPF, UI in Xamarin.Forms are created either in XAML or in C# code entirely. However, it is best to take advantage of its DataBinding support and embrace MVVM (Model-View-ViewModel) pattern. An important point to be noted here is that the controls used in WPF are different from the ones in Xamarin.Forms. Although similar controls are available, often they are named differently to suit the mobile user interface guidelines, and hence the WPF XAML cannot be reused in Xamarin.Forms projects. Read our documentation on WPF vs. Xamarin.Forms: Similarities & Differences.
The interesting thing about porting this WPF app is that 100% of the ViewModels, Helpers, Converters, Models, Services, and any code that does not have platform-specific reference can be reused in the Xamarin.Forms app. Hence even the entire UI logic (ViewModels) is retained, and only the UI (XAML) is freshly created to suit the multi-device mobile form factors. In this sample project, I have created folders called “Legacy” to help you understand what code was reused.
For details on how I built the UI for this sample, refer to the Views folder within the shared project. All the ViewModels from the WPF project have been reused without much modification. Although comparing to the WPF thick client apps, mobile implementations can be much simpler. However, I have retained the logic as-is to exhibit the reuse of maximum code share.
Getting started with Xamarin.Forms
To get started quickly using Xamarin.Forms with Azure Mobile Apps, there is a template in Visual Studio 2017 and Visual Studio for Mac that automatically sets up everything for you. All that you need to do is add your code in the right places.
Create solution in Visual Studio
Open Visual Studio 2017, click on File> New Project>Visual C#> Cross-Platform > Mobile App (Xamarin.Forms). In the next dialog, be sure to check select Master-Detail template, Xamarin.Forms as the UI Technology and choose “Include Azure Mobile Apps backend project” option. Complete the process by selecting an appropriate Azure Subscription and hosting on a preferred Resource Group.
For detailed guidance on building Cross Platform apps using Xamarin.Forms, checkout our Getting-Started guide.
Consuming Azure Mobile Apps backend
The backend code that was ported from WCF to Azure Mobile Apps can be found in the MobileAppService. Explanation of the Mobile Apps backend code is beyond the scope of this article. You can download the source code from my GitHub repo and publish them directly to your Azure Portal.
By default, the template creates a helper class called AzureDataStore that abstracts away the code for offline sync support. I further modified it to fit Expenses project. In this project, we have three scenarios –
- Manage Charges (Add/Edit/Delete Charges)
- Manage Expense Report (Attach charges, Create Expense reports and Submit for approval)
- Manage Employees
To support offline sync for each of the tables, a corresponding Data Store is created that implements IDataStore<T> interface – T being the Model object.
Source Code and Wrap up
You can download the entire source code from my GitHub repo. Refer, the _before folder for the original WPF source and Port-Report folder for Portability analyzer reports. For detailed documentation on porting existing Windows Forms or WPF apps to Android, iOS, macOS, or UWP, refer our Porting Guidance.
Your existing .NET code is more mobile than you think!