Tuesday, November 20, 2012

.Net Portable Subset & Portable Class Libraries

While developing portable class library projects, you might have seen the term portable subset at different places in Visual Studio. Ever wondered what that is? In this post, we are trying to explore this. Just to refresh, you can find an example in the assembly references section of your portable calss library project. If you look at its properties, you find that it is SDK file type. It has .Net Portable v4.0 identity and it refers to a path in the profiles folder.


If we look at the Profiles folder in assembly refernces, we realize that we can find two versions under .Net Portable. They are v4.0 and v4.5.


Basically both of these folders contain profiles. Most of them are contained by v4.0. There is only one profile in v4.5 folder. This is Profile 7.


As discussed in a previous post, we can easily determine the selection of target frameworks for a profile through the supported frameworks folder under profile. Profile7 should be selected for .net framework 4.5 and .net for Windows Store Apps platforms selection.


This profile is used when we target .Net framework 4.5 and .Net for Windows Store Apps. We can easily verify that by retargeting one of our portable class library projects to these versions.


After updating this, we can find that the profile is updated as follows:


So what is the Portable Subset?
Basically Object Browser can be used to see the list of assemblies for a framework or profile (including .net framework client profiles). With Portable Class Libraries, suddenly so many profiles are introduced that it might have seemed that the IDE would clutter up making the life difficult for the developers. This might have pushed the development team at Microsoft to call it sub-set instead. Basically this sub set includes the assemblies referenced in any combination of the target frameworks for the portable class library. So if you see an assembly there, you still might not be sure that it would be available by your selected framework combination. Remember the overlapping area concept we discussed in this post?


Actually this is the same issue when we look at msdn and find that the portable class library support icon with a method / property. Which profile exactly does this mean? We are on our own on this. The feature set chart that we discussed, might help.


These portable versions [v4.0 and v4.5] seem to be referred as .Net Portable subsets in Visual studio. Here v4.5 seems to be referred as .Net Portable Subset and v4.0 seems to appear as .Net Portable Subset (Legacy).

What's Legacy Portable Subset?
As we have seen there is only one frameworks combination that v4.5 provides. It is based on newer frameworks including .net framework 4.5 and .net for Windows Store Apps. Let's try to see what's cooking inside now. Let's try to see if there is a difference in the assemblies for legacy Vs newer profiles. Below is the profile of mscorlib as in Profile 24 for v4.0 Portable folder. As we have discussed in one of our previous post, this is a retargetable assembly.


Now let's look at the mscorlib as in the only profile [Profile 7] in v4.5. Amazingly this is not retargetable. So definitely, there is something cooking inside.


We might verify the same by looking at the other assemblies in a profile for Legacy and New .net portable versions. They all seem to follow the same i.e. all legacy profiles have retargetable assemblies and Profile7 in v4.5 has non-retargetable assemblies. The answer can be found in the reply of David Kean for this question in StackOverflow.

For new platforms (.NET 4.5, Windows Store, Phone 8), we took a step back and designed portability from the get go. Rather than attempt portability as an afterthought, we designed what we call contracts (basically assemblies) that represent a self-contained, unit of code that either a platform supports all of, or none of. This means that when you see "System.IO 4.0.0.0" on .NET Framework 4.5, it supports exactly the same APIs that you will see when you see it on Windows Phone 8. This makes portability very easy, rather than needing to generate custom assemblies to represent the intersection of a platform, we simply subset at the assembly boundary. For example, given a platform 1 that supports System.Runtime.dll, System.Reflection.dll and System.Reflection.Emit.dll and platform 2 that supports System.Runtime.dll and System.Reflection.dll. When you target these platforms in portable, we simply choose System.Runtime.dll and System.Reflection.dll. Long term this makes portability a lot easier to understand, as you can think in terms of assemblies instead of individual APIs.

No comments: