Share functionality using Portable Class Libraries
February 03, 2014
Applies to: Windows Phone 8 | Windows 8
This topic explains what a Portable Class Library is and how you can use it to share code between your apps for Windows Phone 8 and Windows 8.
This topic contains the following sections.
Portable Class Libraries have been available since .NET Framework 4. You can use them to create portable assemblies that can target multiple platforms, including Windows 7, Windows 8, Windows Phone, Silverlight, and Xbox 360, as demonstrated in the following image. Portable Class Libraries support a subset of .NET assemblies that target the platforms you choose. Visual Studio 2012 Pro and greater versions come with a project template that you can use to create Portable Class Libraries. This is a very good way to reduce time and cost by sharing functionality across the platforms you want to support.
You can use Portable Class Libraries to share functionality between your apps for Windows Phone 8 and Windows 8. Note that the Express versions of Visual Studio 2012 don’t include a Portable Class Library project template. The template is available only in Visual Studio 2012 Pro or greater versions. The following diagram demonstrates how both apps share a Portable Class Library. To reference a Portable Class Library, in Solution Explorer, select your project, and then choose Add Reference. Point to either a binary of the Portable Class Library or to the Portable Class Library project.
When you create your app for Windows Phone 8 and Windows 8, you should identify portable code. Place this code in a Portable Class Library and share the portable library between both apps. Portable code has the following characteristics:
Managed (C# or VB) code Portable Class Libraries is a .NET concept and supports managed code only. Because Windows Phone 8 and Windows 8 share the same .NET engine, a lot of the managed code you write, particularly app logic, has the potential to be portable.
Doesn’t use conditional compilation A Portable Class Library is compiled against a set of portable .NET assemblies for the platforms you want to target. If you’re building an app for Windows Phone 8 and Windows 8, this means a set of .NET assemblies that are portable on those platforms. A conditional compilation directive is intended to enable different code paths when the code is compiled for different platforms or configurations. This isn’t the purpose of Portable Class Libraries. If you need to implement functionality for Windows Phone 8 and implement it differently for Windows 8, you can’t include both code paths in a Portable Class Library. Instead, you should abstract away the platform-dependent code and share only the portable, platform-independent code.
Doesn’t use Windows Runtime APIs Windows Runtime APIs aren’t portable and can’t be used in a Portable Class Library. There is overlap in the Windows Runtime APIs that are supported on Windows Phone 8 and Windows 8. However, binary compatibility is not supported. Your code has to be compiled for each platform and therefore isn’t suitable for a Portable Class Library. Here too you should abstract the use of Windows Runtime APIs into classes or objects that aren’t shared in a Portable Class Library.
Doesn’t use UI constructs Although XAML for Windows Phone 8 and Windows 8 looks the same and for the most part UI controls have the same names, this code isn’t portable. Your UI code must be compiled for each platform and therefore isn’t a candidate for placement in a Portable Class Library.
When you create your app for Windows Phone 8 and Windows 8 using the Model-View-ViewModel (MVVM) pattern and using .NET APIs, you have the potential to share a lot of code in a Portable Class Library. Your ViewModel and Model can be designed to be portable and you should place these in a Portable Class Library. The views of your app, and the startup code, typically are platform-specific and should be implemented in your Windows Phone 8 and Windows 8 app projects. This is illustrated in the following diagram.
If your ViewModel needs to call platform-specific code, you should abstract that functionality into the platform-independent interface and use the interface in the Portable Class Library. The interface can then be implemented in a platform-specific way in each app project. This is a very powerful code-sharing technique and allows binary sharing because the Portable Class Library is compiled once and then used in multiple platforms.