Dajbych.net


Portable Libraries – one library for all platforms

, 7 minutes to read

net2010 logo

The Portable Class Library is a universal .NET library. It’s useful for sharing code between WPF, Windows Phone, and Metro-style apps, for example. It can contain everything that is common to the platforms for which it is intended. With the Visual Studio 2010 Add-in, you can start using it immediately. As the .NET platform has been somewhat fragmented in recent years, the Portable Library is a very welcome cementing element. It is no longer necessary to compile libraries for different .NET platforms.

Introduction

Previously, it was just .NET Framework. After some time, however, Silverlight appeared, then Windows Phone, followed by Xbox 360 and now Windows Runtime. That’s already 5 different platforms running .NET. However, because each platform is very specific in its own way, the types on each platform are always a little different. It probably doesn't make sense for the Xbox 360 to support touch as a Metro style app or to include support for Windows Forms. Windows Phone does not need a massive ADO.NET and Entity Framework for its SQL Server Compact, but it will make do with a thinner layer that can provide Code-First access and LINQ support as well. Silverlight must have completely different classes to access the file system. Portable Library allows you to choose the platforms for which you want to develop. We then have everything these platforms have in common. The library then runs on all selected platforms.

Often, one application is created for several platforms. A Portable Library typically contains code that would be the same in all profiles and is needed on each profile. It is not a user interface, because each device has a different one, but above all the main logic of the application. The Portable Library is mainly for Model and ViewModel, and may also contain a service reference.

Use

The Portable Library can be used with Silverlight, Xbox 360, Windows Phone 7, Windows Phone 8, Windows Runtime (Windows Metro style apps), and the large .NET Framework. The Portable Class Library can't target the .NET Micro Framework and SQL Server CLR. The project with Portable Library can then be opened in both Visual Studio 2012 and 2010, but it is necessary to install the Portable Library Tools 2 add-on from the Base Class Library team.

After you install the add-in, a new project type will appear.

When creating it, it is first necessary to choose the profiles for which we want to develop.

In January 2011, the first version for Visual Studio 2010 was released. It enabled basic functionality that was supposed to be appealing enough for developers to try and send feedback to the BCL team.

The second version for Visual Studio 2010, released in May 2012, is no different in terms of capabilities from the one in Visual Studio 2012.

In Visual Studio 2012, support is already built in.

What’s supported

Feature AreaSilverlight 4Silverlight 5Windows Phone 7Windows Phone 7.1Metro Style Apps.NET Framework 4.NET Framework 4.0.3.NET Framework 4.5XBOX 360
Core XML
LINQ
IQueryable
dynamic keyword support
Core WCF
Core Networking
View Models
Data Annotations
XLINQ
MEF
Data Contract Serialization
XML Serialization
JSon Serialization
System.Numerics
Task<T> support

Architecture with Portable Library

The basic principle is to create an abstract class that represents the Model. It has implemented everything that is common to all platforms. This model is located in the Portable Library. There is also a ViewModel, which has a parameter in the constructor that passes a reference to a specific model from a specific platform that inherits from the abstract model.

In practice, however, it is not that simple. The keywords async and await are typically not known to all the platforms we need to target them to. That’s why we need another interface. I have created a demo that illustrates the basic principle. Thanks to Daniel Plaisted for providing the source code for the task wrappers.

Source codes of the demo for download.

How it works

Profiles

The most common profile that most programmers have probably encountered is the .NET Framework Client Profile. It’s a subset of the .NET Framework for client-side applications. It does not contain ASP.NET, but it does contain Windows Forms and WPF. However, Silverlight is a platform profile because it has a different implementation than the large .NET Framework. It contains a different mscorelib.dll. The same is true for Windows Phone.

A profile is represented by a set of reference assemblies. These assemblies do not contain IL (Intermediate Language) instructions, but only contain metadata. The compiler needs metadata to know which calls the application can make. Reference assemblies for the Metro style (Windows Runtime) profile can be found in the C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETCore directory. You will see *mscorelib.*dll and System.Collections.dll in it. But why is this library especially when collections are implemented in mscorelib.dll? The .NET platform consists of several layers that are very carefully separated from each other. For example, mscorelib is not dependent on ASP.NET. Over time, as the number of environments where .NET is used gradually increased, it turned out that it would be good to divide some elements and place them in different layers. Profiles try to remedy this shortcoming. Therefore, System.Collections.dll and System.Reflection.dll are separate from System.Runtime.dll (which is the new name for mscorelib.dll).

Platform fragmentation

Different .NET platforms have a lot in common, but they are also fundamentally different. Silverlight has a different implementation of mscorelib. Xbox 360 is based on the .NET Compact Framework. The large .NET contains ASP.NET that doesn't make sense elsewhere, such as on Windows Phone.

The platforms differ from each other mainly in terms of user interface. The INotifyPropertyChanged interface is the core of the ViewModel. In Silverlight, it is located in the library System.Windows.dll, in . NET library, however, Systém.dll. MEF (Managed Extensibility Framework) occurs both in large . NET and Silverlight. However, you won't find it on Xbox 360 or Windows Phone. If you uncheck them, you can program modules. As soon as you check Xbox 360, you lose your networking stack.

Using the original functionality for the .NET Compact Framework

A strong type contains the name of the assembly, its version number, the hash of the public key used to sign it, and the retargetable bit. It was used for the ability to run an application programmed against the .NET Compact Framework on a desktop where the .NET Framework is large. This bit is important for the CLR, which contains a hard-coded table that says, “If you see assembly A with the retargetable bit set, use assembly B instead.”

If the Portable Library contains a reference to System.Net.dll that contains a networkign stack, the retargetable flag is set. In Silverlight, this library exists, but in a big way. NET’s functionality is directly in System.Core.dll. Therefore, it is necessary to create a shadow assembly that will only refer to types located in another assembly.

Type forwarding

Type forwarding is what makes profiles work. An assembly does not have to contain the type itself and its implementation, but instead it can only contain a type with metadata that tells where the type actually is. The Portable Library is programmed against the profile here. You can find it in the C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETPortable directory. These libraries are technically assemblies, but they only contain metadata. The Portable Library doesn't actually contain references to specific libraries (although technically it still is), but a reference to a library with metadata. This type of reference is called API Contract.

TypeRef, TypeSpec, and TypeDef

If an assembly A uses a type from another assembly B, it actually contains only TypeRef. TypeRef points to TypeSpec, which describes the type and is located in the assembly with metadata, compared to which assembly A is compiled. Assembly B, which is located on a particular platform, contains TypeDef, which is tied to TypeInfo. TypeSpec contains enough information to describe the type, but does not contain as much as TypeInfo. The CLR takes care of linking TypeSpec from the profile with TypeDef from the platform. This introduction of TypeSpec and TypeDef is the biggest visible change in the .NET Framework in recent years. It allows portable libraries to run on platforms that will be released in the future, as long as they contain a subset of the Portable Library against which it is programmed.

The article was written for the Czech MSDN Blog.