As we build applications for more and more platforms, it is extremely important that we maximize our code reuse across platforms. With the release of Windows 8 and Windows Phone 8, Microsoft has made significant improvements in platform convergence – this convergence will continue with each release. They share the same core as Windows, and Microsoft removed .NET compact framework and replaced it with CoreCLR and added WinRT. Much of this is common to Windows 8 itself.
However, it is important to understand that these are still two distinct platforms and still do not have 100% convergence with binary compatibility. Maximizing reuse across these platforms is key to an efficient development experience.
Portable Class Libraries
.NET 4 introduced Portable Class Libraries (PCL). These assemblies can be used to target different platforms including Windows 7, Windows 8, Windows Phone, Silverlight and Xbox 360. Only a subset of the .NET framework is supported in PCLs – for example, it would not make sense for a PCL to support the API to interact with MSMQ because that does not even exist on the Windows Phone platform. In general, APIs that deal with File I/O or user interface are not PCL compliant.
Portable Class Libraries support code that can clearly be used across platforms. These types of assemblies can be referenced as project references inside Visual Studio like any other project and can also be distributed as part of a NuGet package. Fortunately, Microsoft has been moving more and more code to be PCL compliant, including this recent release of a portable HttpClient!
An ideal use of a PCL is to include code that represents your domain model and business logic. Often these classes include core POCO (Plain Old CLR Objects) objects that can be easily used across platforms. If you have types that represent HTTP payloads going across the wire, this is another ideal use of PCL as you can create a reusable service agent layer.
You can add a new Portable Class Library project to your solution by selecting the “Portable Class Library” project type in the “Add New Project” dialog in Visual Studio. Once you do this, you will be prompted to specify which platforms you want your PCL to support:
Separate UI Form App Logic
Separating your presentation logic from your application logic is generally a good idea in any application for good Separation of Concerns (SoC). However, this is even more important in your cross-platform applications. A common pattern for organizing code is the Model-View-ViewModel (MVVM) pattern.
- Model – This represents your domain model or perhaps the entities you consume across the wire from HTTP services.
- ViewModel – This model is view-specific and contains presentation logic.
- View – This represents the visual aspect of your application. This is typically a markup layer such as XAML or HTML.
By leveraging Portable Class Libraries and MVVM together, we can create an assembly that can be used in both a Windows Store app and a Windows Phone 8 app:
Quite often you will need different view models between your Windows Store app and your Windows Phone app. In this case, it is not advantageous to put your view models in your PCL. The most common recommendation is to put your models and business logic in a reusable PCL and put your platform-specific view models in the respective User Interface tiers.
These days, MVVM is a ubiquitous pattern in mobile development on the Microsoft platform. There are many high-quality libraries available today that can help you implement the MVVM pattern. One of the most widely-used libraries is the MVVM Light Toolkit which can be found on CodePlex.
Linking Source Files
Linking source files is a technique that has been available in Visual Studio for years. This technique is for many different reasons, but is particularly useful when sharing common code across platforms. Usually, utilizing a Portable Class Library is the most desirable option. However, there are certain situations where the code is not PCL-compliant but it could still be used in multiple projects. A typical example would be if you are using the Windows Runtime API (which is not fully PCL-compliant). But since both Windows Store apps and Windows Phone 8 apps share a subset of the Windows Runtime API, it is possible to inject this shared code into your project by using linked files.
Additionally, you can use cross-platform conditional compilations symbols (e.g., WINDOWS_PHONE, NETFX_CORE, WINDOWS, XBOX) to further refine your code. It is interesting that only a subset of the WinRT API is supported, and I have not seen any clear explanation from Microsoft as to why this is the case. For example, there is no reason (that I can see) why the Windows.Storage namespace isn’t available on Windows Phone 8.
Sharing a linked file means that the file is physically located in only one location but there is a virtual link to the code file in multiple places, as shown below:
View Considerations
XAML is supported in both Windows Store apps and Windows Phone apps. Windows Store apps also support HMTL5/CSS for building the view, but it is important to note that HTML view is currently not supported in Windows Phone apps. A common misconception is that since XAML is supported in both Windows Store apps and Windows Phone apps, the XAML can be reused across both platforms. This is simply not true! In fact, XAML cannot be shared between these two platforms because of binary incompatibility. The available controls are similar but these are two different controls contains in two distinct SDKs.
It is possible to get some XAML reuse by creating basic user controls. However, not only is this technique limited but it also does not scale well. A better approach is to focus on building XAML views that will result in vibrant user interfaces that are optimized for a particular device, including screen resolution, native gestures and features.
Conclusion
Windows 8 and Windows Phone 8 offer an exciting new opportunity for building cross-platform apps. However, several considerations must be taken into account when designing your apps. The most important aspects to facilitate reuse for a cross-platform application are:
- Leveraging Portable Class Libraries effectively
- Leveraging the Model-View-ViewModel pattern
- Leveraging Linked Files where appropriate
Thanks to Balachandra Mamillapalli for contributing research to this post.