Performing code reuse in Windows Phone
Today there are multiple platforms in the Windows universe that you might want to service with your apps. Keeping versions for Windows Phone 7, Windows Phone 8 and Windows 8 is a common scenario. Developing multiple versions of an app however should not multiply work. Here are some tips how to avoid duplicate work and keep the app maintainable.
A typical Windows Phone solution consists of code, resources (resx), xaml, styles and other assets like images or (static) data files. Being able to share the biggest part of it can significantly reduce your workload and improve maintainability. There are different ways to reuse code and the other items in a solution. Here we present an overview with links to background articles.
In a recent, featured discussion on the ND Discussion Board (Thread: Performing code reuse in Windows Phone 8) it's postulated that some elements can be shared and some can't be shared. As we'll see later the list of sharable elements is long and with good ideas problems might be overcome. The example for this are the resources that can be shared if the differences for the platforms are small and the resource namespaces can be kept equal.
If the readers have solutions for other problematic elements the community would gratefully honor an article describing the solution.
The most important preparation is to divide code from the UI. You might object now that the division of the XAML UI from the code-behind in C# is enough but in order to create different UIs for the platforms the code should not be tied so strongly to the UI. One solution here is the MVVM pattern Understanding the Model-View-ViewModel Pattern. What you can gain additionally is so-called 'Blendability', i.e. a rich design experience in Microsoft Blend. There are lots of articles, videos/webcasts on MVVM and several toolkits proposing to simplify it's usage.
Ways to reuse code
There are different approaches to sharing the elements of a solution. In MSDN there's a very good overview of some of the techniques that can be used to share code and XAML, Maximize code reuse between Windows Phone 8 and Windows 8. Sharing resources is not covered there.
The following list shows the techniques grouped by type of solution element:
Multiple types (works for code, resources, images. assets...)
- Copy/Paste - Copying and pasting code is dangerous and may lead to subsequent bugs.
- Using Add as Link - The most important trick. Visual Studio allows to link a single source file into multiple projects. This way a change in one project can automatically replicate to another project.
With code there are many options to share complete assemblies, complete source files or parts of them.
- Putting code in a separate assembly and referencing it - The ideal occurrence are Portable Class Libraries (PCL, see below). If not using PCL it's difficult to use managed code because of differencies in the .net framework base libraries. Unmanaged code, i.e. DLLs written in C/C++, should be simple to share across platforms.
- Using portable class libraries - There are many discussions about Portable Class Libraries (PCL). In my opinion they are one of the most interesting concepts for code reuse. There are even (commercial) tools that allow to share code for Android and iOS using PCLs.
- Using preprocessor directives - Preprocessor directive are used in conjunction with Copy/Paste (arghh) and 'Add as Link' to circumvent small differences in code. They are usable in C++ and C# code but not in XAML. MSDN has a nice article.
Resources present a special challenge, because there are no simple ways to conditionally switch parts of resource files. If the greater parts of your resources (strings) are identical, you can use the following techniques:
- Implementing a datasource in code that gives different strings for the different versions - One advantage is that you can use preprocessor defines here.
- Implementing a value converter (as this is code, too, you can use preprocessor defines)
XAML files pose comparable problems as resources. However, some parts of them can be put into static resources. You can use static resources for storing strings or data. The most important problems here are different namespaces in Windows and Windows Phone and differences in the controls themselves. Due to the screen size constraints the XAML UIs should be developed individually anyway.(TODO)
- Using preprocessor directives - Not usable like in C# code, but there are some articles descibing methods to use conditional interpretation of XAML code:
Beginning with Visual Studio 2013, support for Windows Phone 7 is dropped. So upgrading an elder solution poses problems:
Reusing code or other solution assets can save a lot of time and improve the stability of multi-platform projects. The details however can be a little tricky for some kinds of solution items.