Portable Class Library is a universal .NET library. It is designed for sharing source code for example among WPF, Windows Phone and Metro style applications. It may contain everything common from target platforms. Thanks to the Visual Studio 2010 extension you can start use it immediately. Due to .NET Framework fragmentation the Portable Library is welcome unification element. It is not necessary to compile libraries against multiple .NET platforms anymore.
Initially we had the .NET Framework. Later the Silverlight was added then also the Windows Phone, next the Xbox 360 and the Windows Runtime is coming. It is about 5 platforms where .NET runs. Types containing each of them are slightly different because every platform is very specific. There is no reason to support touch in Xbox 360 like in Metro style app or Windows Forms. Windows Phone doesn’t need for its SQL Server Compact or huge ADO.NET and Entity Framework, but a tiny layer accessing Code-First approach and LINQ is enough. The Silverlight must have different classes to access the file system. Portable Library allows choosing platforms we want develop against. The library then runs on chosen platforms.
It is often needed to develop an application for multiple platforms. The Portable Library typically contains code which would be the same on all platforms you want to share. It is not the user interface, which is different on each platform, but mostly the main application logic. Portable Library is ordinary for Model and ViewModel and can contain even service reference.
Portable Library is applicable to Silverlight, Xbox 360, Windows Phone 7, Windows Phone 8, Windows Runtime (Windows Metro style app) and full .NET Framework. Portable Class Library cannot be used with .NET Micro Framework or SQL Server CLR. The Portable Library project could be opened by both Visual Studio 2012 and 2010 if the Portable Library Tools 2 extension by Base Class Library team is installed.
The extension adds a new project type.
At the beginning is necessary to choose target platforms.
The first version was released on January 2011 for Visual Studio 2010. It contained basic functionality to be interested enough for developers to try it and send feedback to the BCL team.
The second version for Visual Studio 2010 was released on May 2012. It allows as much functionality as Visual Studio 2012 version.
At Visual Studio 2012 is Portable Library built in.
What is supported
|Feature Area ||Silverlight ||Windows Phone ||Metro Style Apps ||.NET Framework ||Xbox 360 |
|4 ||5 ||7 ||7.1 ||4 ||4.0.3 ||4.5 |
|Core BCL ||X ||X ||X ||X ||X ||X ||X ||X ||X |
|Core XML ||X ||X ||X ||X ||X ||X ||X ||X ||X |
|LINQ ||X ||X ||X ||X ||X ||X ||X ||X || |
|IQueryable ||X ||X || ||X ||X ||X ||X ||X || |
|dynamic keyword support ||X ||X || || ||X || || ||X || |
|Core WCF ||X ||X ||X ||X ||X ||X ||X ||X || |
|Core Networking ||X ||X ||X ||X ||X ||X ||X ||X || |
|View Models ||X ||X ||X ||X ||X || || ||X || |
|Data Annotations ||X ||X || || ||X || ||X ||X || |
|XLINQ ||X ||X ||X ||X ||X || ||X ||X ||X |
|MEF ||X ||X || || ||X ||X ||X ||X || |
|Data Contract Serialization ||X ||X ||X ||X ||X ||X ||X ||X || |
|XML Serialization ||X ||X ||X ||X ||X ||X ||X ||X || |
|JSon Serialization ||X ||X ||X ||X ||X ||X ||X ||X || |
|System.Numerics ||X ||X || || ||X ||X ||X ||X || |
|Task<T> support || || || || ||X ||X ||X ||X || |
Architecture with Portable Library
The idea is based on the abstract class which represents the Model. It contains the implementation of all the common code from each platform. This model is located in the Portable Library. There is also a ViewModel which has a parameter in its constructor to pass a reference to the platform specific model implementation derived from the abstract model.
From the practical view it is not that simple. The async & await keywords are not typically supported on each platform you want target to. That’s why some additional interfaces are required. I created a simple demo to illustrate the most common patters. Thank you to Daniel Plaisted for providing me the source code of task wrappers.
How it works
The most common profile, which many of developers already meet with, is the .NET Framework Client Profile. It is a subset of the full .NET Framework for building desktop applications. ASP.NET is not included there, but it contains Windows Forms and WPF. The Silverlight is a platform profile because it has s different implementation compared to .NET Framework. Its mscorelib.dll is not the same as is in the full .NET Framework. The same is the Windows Phone.
The profile is represented by set of reference assemblies. Those assemblies do not contain IL (Intermediate Language) instructions but contains the metadata instead. Compiler needs metadata to know which API calls are valid. Reference assemblies for Metro style (Windows Runtime) profile are located in C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETCore. You can see there the mscorelib. and the System.Collections.dll. Why is this library separated when all collections are implemented in mscorelib.dll? The .NET platform contains several layers. Dependencies among them are very carefully managed. For example mscorelib.dll does not depend on ASP.NET. There are some places where in retrospective is a mistake. There are some items which now would be eligible to be separated. Profiles are trying to fix this. That’s why the System.Collections.dll and the System.Reflections.dll are separated from the System.Runtime.dll (which is another name for mscorelib.dll).
All .NET platforms have many common but they also differ from each other. The Silverlight has a different mscorelib implementation. The Xbox 360 is based on the .NET Compact Framework. The full .NET contains ASP.NET which does not make sense elsewhere for example on the Windows Phone.
Platforms are specific mostly because of the user interface. The interface INotifyPropertyChanged is the core of ViewModel. In the Silverlight it is located in the System.Windows.dll library unlike in the full .NET where is located in the System.dll library. MEF (Managed Extensibility Framework) is contained in the full .NET and in the Silverlight but not in the Xbox 360 or the Windows Phone. If you unselect them you can develop modules. When you select the Xbox 360 you cannot use the networking stack.
Using the functionality for the .NET Compact Framework
The strong type is composed by assembly name, version number, public key token and retargetable bit. It used to allow running an application developed against .NET Compact Framework on the desktop where is the full .NET Framework. This flag is important for the CLR which contains hardcoded table which tells: “When you see whatever assembly A with set retargetable flag use assembly B instead.”
When the Portable Library has a reference to the System.Net.dll which contains implementation of the networking stack the retargetable flag is set. This library exists in the Silverlight but in the full .NET is its functionality built in the System.Core.dll. What’s why is necessary to create a shadow assembly to forward types located in another assembly.
Profiles are working thanks to type forwarding. The assembly does not have to contain the type with its implementation but it can contain just a type with its metadata. The metadata tells where the actual type is located. The Portable Library is built against a profile. It is located in C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETPortable. Those libraries are technically assemblies but contain only metadata. In fact Portable Library does not contain references to specific library (but technically still contain) but references to metadata libraries. This kind of reference is called API Contract.
TypeRef, TypeSpec and TypeDef
When some assembly A is using a type from another assembly B in fact it contains just a TypeRef. The TypeRef is pointing to the TypeSpec which describes the type. It is located in the metadata assembly which is the A assembly compiled against. The assembly B which is located in the specific platform contains a TypeDef which is related to the TypeInfo. The TypeSpec contains enough information to describe the type but not as much as the TypeInfo. The CLR is managing the mapping between the TypeSpec from the profile to the TypeDef from the platform. Introduction of the TypeSpec and the TypeDef is the biggest visible change in the .NET Framework during the last period of time. It allows Portable Library to run on platforms which will be released in future if they contain a subset which the Portable Library is developed against.