Scott Hanselman

Hidden Gems in Visual Studio 11 Beta - .NET Portable Class Libraries

April 05, 2012 Comment on this post [28] Posted in Learning .NET
Sponsored By

.NET Portable SubsetI'm realizing there's a number of subtle but important new things in the next version of VS that streamline some previously difficult tasks. For example, there's the .NET Framework, but .NET is also in Silverlight, the Windows Phone, the Xbox, etc.

If you create a regular Class Library it has a single Target Framework. However, if you are doing a multi-platform application and you want to maximize your code reuse, you can run into trouble as you may not have all libraries available on the smaller platforms.

Thus, Portable Class Libraries were created. You can get Portable Class Libraries via an extension on Visual Studio 2010 or they are built into Visual Studio 11 Beta.

These Portable Class Libraries (PCLs) will generate a managed assembly that can be referenced by Windows Phone 7, Silverlight, the Microsoft .NET Framework and Xbox 360 platforms. This really helps to maximize reuse of code and reduce the number of projects in multi-targeted application solutions.

I talked about multi-targeting a little in the .NET Versioning and Multi-Targeting - .NET 4.5 is an in-place upgrade to .NET 4.0 post. Visual Studio is smart enough to tell you before compilation what APIs are available. The compiler knows and Intellisense knows. The Reference Assemblies down in C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\ tell you a lot.

Reference Assemblies include .NET Portable Assemblies

If you create a new Portable Class Library, right click on it and hit Properties. You can target specific frameworks and the build system and Intellisense will adjust. Some libraries are on some device. For example, XML Serialization isn't on the Xbox 360, but WCF is on the Windows Phone.

Select the Frameworks you want

Bill Kratochvil has an article in MSDN Magazine that includes the source for a project that targets Windows Phone 7, Silverlight and WPF with shared libraries. David Kean has an article this month in MSDN Mag on how to Create a Continuous Client Using Portable Class Libraries.

Remember that Portable Class Libraries are constrained by design. You're targeting the lowest common denominator to maximize what you can use between projects. The MSDN article on Portable Class Libraries has a table that show what's available on each platform. You can do MVVM work across Windows, Metro style aopps, Silverlight and Windows Phone, for example.

Here's some good advice that David Kean sent me:

One thing [about] using portable [is that it] doesn’t mean you can’t use platform specific features, you just need to spend a little more time thinking about your dependencies. For example, instead of having a low level class that handles your persistence layer using the File APIs (which aren’t usable/available on Phone, Silverlight, etc), have it instead take work on an abstraction such as a stream, which these gets passed that from the platform specific project. Or have it call through an platform adapter (called out in my article), or inject the abstraction using your favorite IoC container (in my case Autofac, just published a portable version)

MSDN Help also shows what works with Portable Libraries as well so you're supported when looking at Help, Intellisense, and at Build time.

image

The BCL Blog mentioned that they are talking to the Mono guys about this as well. It'd be great to get Mono for Android and other frameworks as appropriate in here as well. I was excited to discover that this work was happening, even though it's been over a year in the making.

For folks like my friends at Rowi who have a great Windows Phone 7 application, or MetroTwit with a great WPF app, I wonder how Portable Class Libraries might change the architecture of their applications and enable cleaner builds and reuse scenarios they haven't thought of.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Hosting By
Hosted in an Azure App Service
April 05, 2012 22:27
I blogged about this just yesterday. The portable libraries are still a little mixed up, but there's great promise (hopefully by the time VS11 ships). For instance, there's many types that exist across all "platforms", such as ICommand and ObservableCollection, that you won't have access to if you choose .NET 4 (or below) as one of the targets. However, pick .NET 4.5 and everything is golden. Then there's the fact that while you can target the phone, you can't do actual phone development in VS11 beta. The potential is there, but actually using it today is problematic, to say the least.
April 05, 2012 22:28
I hadn't really spent much time with them not really coming up with a good use case for them. Reading this I can think of a half a dozen libraries (including Json.NET and MVVM Light) that would benefit from using this feature and reduce the project sizes and complexity. There's an OSS project that I contribute to that could make use of this and (potentially) eliminate 2 extra projects in the solution. Nice.
Bil
April 05, 2012 22:44
I think it would be interested to eventually include Mono in the Target Frameworks. Also, I could see Portable Class Libraries eventually replacing all framework-specific libraries.
April 05, 2012 22:47
Karl - I'm not sure if Mono would make as much sense. We'd have to see if Miguel chimes in. Smaller frameworks like Mono for Android seem like a good idea.
April 05, 2012 22:47
Sadly, most of the MVVM libraries out there aren't going to be able to benefit from this...because just about all of them have to take some platform-specific dependency at some point, which is not currently portable. For example, virtually every feature in Caliburn.Micro that distinguishes it from other "MVVM Frameworks" cannot be built on top of portable libraries.

It will be interesting to see if there is enough supported to enable established open source projects to run on top without much alteration: IoC tools, mapping tools, service clients, etc.

Has any major open source project actually moved to portable libraries yet? I'd like to know which ones and read a case study.
Rob
April 05, 2012 22:47
There's a big use case you're missing there Bil... being able to use regular unit testing frameworks and test runners on Silverlight and Phone projects. Put the Models, ViewModels and other non-View code in a portable library that includes .NET 4.5 and you can unit test that code normally. So, even if you're writing code you only plan to use on the Phone, for example, the portable library stuff is still useful.
April 05, 2012 22:49
Rob - What's major? You see the link to Autofac above. Bill Kempf has the right idea as well. I think the point wouldn't be to shoehorn Caliburn into a Portable, but rather to think about what aspects of Calburn would make sense in Portable. Perhaps 30%?
April 05, 2012 23:01
Oops. I missed the link to Autofac in the post. Yes, I would consider that a significant project.

Regarding Caliburn.Micro...I'm not sure it would be worth the effort if only 30% of it could be put into a portable library. Plus, then I'd have to split it into multiple assemblies...and do some major re-architecture to work out the dependencies, just for the 30%. In the end, I don't think it would result in a net maintenance win for me, especially since I have so much conditional compilation code that is around sorting out the differences in Xaml implementations...which is definitely one reason why devs use Caliburn.Micro.

I like portable libraries. I hope it works for a lot of projects out there, but I don't think it will work for me. It seems like a rather intricate band-aid that's trying to fix up the lack of long-term vision for .NET that we've seen up to this point. Frankly, there was zero reason for API incompatibilities across Xaml implementations. But, now we are left with the pain...and who knows if portable libraries will ever be able to fix this up. Hopefully, the .NET team will learn something from this.
Rob
April 05, 2012 23:23
Bill,
I'd be interested in reading your blog post but couldn't find it with some quick searching. Can you link us to it?


Rob,

I think in Caliburn's case the benefit of portable libraries would be for people using Caliburn as opposed to making it easier on you as Caliburn's developer. The portable part of Caliburn would be everything the ViewModels need to reference, so that people writing apps for different platforms could use the same portable ViewModels across all of them. The implementation Caliburn's conventions which bind the ViewModels to the UI would still be platform specific.

Of course that would be a lot of work, and until more people start trying to create portable ViewModels it's not certain that it would be a huge benefit. One thing that I think would be cool about it is that it might enable ViewModels to be portable to .NET 4. Most non-Caliburn ViewModels need ICommand which is only portable to .NET 4.5, but with Caliburn you just have an ExecuteCommand() method and a CanExecuteCommand property and you don't need ICommand at all.
April 05, 2012 23:25
I think it got out of control, but "there was zero reason for API incompatibilities across Xaml implementations" is simply wrong. There was, and is, a valid reason: size of the framework. Especially on the phone, it has to be kept small, and the desktop framework is anything but small. I actually think the portable library approach is the correct one, and not "a bandaid" at all. The only problem is really with it not being complete enough and pervasive enough today. I spend too much time fighting the little things, like types not included that should have been and tooling support problems.
April 05, 2012 23:39
Daniel,
Sorry, I didn't intend to link bait, especially when my post is only indirectly related to this one, which is why I left the link out. Since you asked for it, however, here it is: http://digitaltapestry.net/blog/waiting-for-nirvana. The post is basically about how one would want to use the portable library approach to solve the unit testing problem, and how we see the promise of it with VS11 but still can't fully get there. I'm actually doing it anway, switching back and forth between IDEs, with the hope (pretty much a given, but something theoretically could go wrong here) that when VS11 ships I will no longer have to deal with these issues.

I agree with most of what you said about Caliburn. However, I'm not sure I understand your comments about ICommand. ICommand has existed in .NET since the release of WPF in .NET 3. It's also existed in Silverlight for some time now (3? For sure in 4.). The issues surrounding ICommand, which still exist today, surround the View not the ViewModel (Silverlight and the Phone don't have ICommandSource and have only recently added the Command parameter to buttons, and only buttons). However, AFAIK, all MVVM libraries provide their own solutions to this problem.
April 05, 2012 23:50
@Bill

Yes, that was probably an exaggeration. I'm not talking about things that were left out for size reasons. I'm talking about methods with different names, different signatures, or just different behavior even when everything on the surface looks the same. I'm talking about properties that moved from one type to another, different class hierarchies, etc. There are literally hundreds of things that were changed for no apparent reason...and I'm sure it had nothing to do with size. Those things are the ones which cause me so much pain.

@Daniel

I agree. But it's easier said than done. I haven't written off the possibility, but right now...I don't have time, and no one seems to be interested in helping with this sort of thing.

Also, apologies to everyone reading this. I didn't intend to start ranting here. Portable Libraries are actually a good thing and will probably work well for a large set of scenarios.
Rob
April 05, 2012 23:51
Bill: If you check out my interview on Channel 9 (.NET 4.5: David Kean and Mircea Trofin - Portable Libraries), I try to get across some of the complexity around trying get portable library to support existing platforms. With regards to ICommand, etc and .NET 4.0, it wasn't possible to add the support for it without shipping another update to it. For reasons I won't go into, in the past portability was not as an important goal for the various .NET platforms, so you would see differences that made this difficult. This has now changed, and we're investing heavily into it. Towards the middle of the video, we explain how things are changing in the future for new platforms.

Also, there's a couple of things that make developing for Phone easier while using VS11:
- We've just release an update for Phone SDK (7.1.1) that enables you to install and use the SDK on Windows 8.
- We support VS2010 SP1 + VS11 sharing the same projects and solutions for projects that are supported in both. If you look at my article linked above, you'll see my solution layout that enables you to develop a Windows Phone and Metro app at the same time.

Rob: Thanks for the feedback. I'm yet to tackle Caliburn.Micro, but we had a go doing a private port of MVVMLight and got Laurent's projects down to 5 from 18. There's massive benefit in that - for the most part, you don't need to test the thing umpteen different times, less playing around with linked files and projects. Plus, you've now benefited those who've started using portable libraries for their apps. We're also not pretending that portable libraries are a replacement for platform-specific projects. For starters, your views between your Phone and tablet are likely to be different, and there's always going to be platform-specific features that you'll want to take advantage of or features that a platform lacks due to size, time or security restrictions. One thing we are looking at heavily though, is ways of enabling you to target additional features that may not be available everywhere within the same portable project.

With regards to the multi-assembly thing, is that because people hate referencing multiple assemblies? Does Nuget help with that? Would a way to reference and consume Caliburn as a single unit help?
April 06, 2012 0:00
Bill,

Of course ICommand is available on .NET 4, but it is not available in a portable library that targets .NET 4. The reason for this is that it lives in a different assembly: PresentationCore.dll for .NET 4 and System.Windows.dll for Silverlight. Because .NET 4 had already shipped, we couldn't make ICommand portable between .NET 4 and Silverlight/Windows Phone. In .NET 4.5, we were able to make changes to make it portable.

If you are interested in some of the technical details behind how all of this works, this Channel 9 video is a great one to watch: .NET 4.5: David Kean and Mircea Trofin - Portable Libraries

That video also goes into the differences between adding portability after the fact (a "band-aid" as Rob says) versus how we are designing for portability for the future.

Oh yeah, and it also covers why we changed the reflection APIs (ie you have to call GetTypeInfo()) for Metro style apps, if you're interested in that. :)
April 06, 2012 0:05
@David

Thanks for the video link. I'll check it out tomorrow.
Nuget would help with the multiple assembly issue, yes. But, don't assume that because you had moderate success with MVVMLight that the same would be true of Caliburn.Micro. They are two completely different creatures. For starters, I have a big dependency on System.Windows.Interactivity. That probably prevents moving to portable libraries itself. It would require...a massive refactoring to sort that out.

Ok. Let's not talk about Caliburn.Micro here anymore. Even I'm getting annoyed by hearing about it now ;) Anyone who wants to discuss further, please feel free to email me.
Rob
April 06, 2012 0:14
@David

I'm really glad to hear that portability is being planned for in the future. I just wish it had been a priority from the beginning. I wish I could get back the time I lost. Honestly, I'm pretty beat down by the yearly platform changes that cause me to do massive porting work or altogether re-writes...just after I think I've got everything working again. The damage is done for me, as far as my desire to participate in .NET open source. Hopefully the work you are doing can prevent that from happening to others in the future.
Rob
April 06, 2012 0:15
Good thing Object is in the portable class library ;-)
April 06, 2012 0:35
David Kean,
The new SDK working on Windows 8 means little to me. I'm not targeting WinRT yet, so that's a non-issue. As for you're other point... that's pretty much what my blog post said you could do. Bounce back and forth between IDEs. It works, but it's painful, and I doubt most people will bother. Once we have a Phone SDK compatible with VS11 I expect the pain points to go away, at least for my use cases.

Daniel Plaisted,
Ahh, I understand what you were saying now. At least I understand why you were mentioning ICommand in .NET 4.5. I have to say I still don't understand why the portable library system couldn't work with .NET 4/3.5/3, though. What little I know about how the "magic" works comes from this series of blog posts: http://csharperimage.jeremylikness.com/2012/03/understanding-portable-library-by.html. ICommand still lives in different assemblies across desktop/silverlight, and WinRT creates an even bigger discrepency. Yet when you target .NET 4.5 you can reference ICommand across all of those platforms. I'll have to watch the video you and David both linked to see if I can grok the reasoning here. In any case, the problem today is mostly one of tooling. Even though the portable library system has been around for a while now, we're still not at a point of being able to really make use of it without some major pain points. Prior to VS11 it was with both the tooling and the (lack of) APIs and now it's mostly just a tooling problem. However, that's still a big barrier... one I hope is removed soon. :)
April 06, 2012 0:42
FYI, I learned the hard way that the Portable Class Library (PCL) is no longer the least common denominator, Metro is.

My port of Unity to the Portable Class Library compiled successfully under Metro WinRt but when I attempted to run the application that included the PCL. I would get a "Could not load file or assembly...". I blog on the topic => http://www.global-webnet.com/Blog/post/2012/01/08/METRO-Portable-Class-Library-=gt;-Could-not-load-file-or-assembly-SystemCore-Version=2050.aspx
April 06, 2012 0:52
Bill Kratochvil
It looks like you wrote that post before the Beta of VS Dev11 was released. Can you try again using the Beta? A lot of stuff changed between the Developer Preview and the Beta so the "Could not load file or assembly..." issue is probably fixed.
April 06, 2012 0:59
Portable Library Support is something that we would like to support in Mono.

We had some discussions with the .NET team a year ago, but they didn't go anywhere.

Having the entire subset of the portable libraries in Mono is not the problem, the real problem is doing all the work to create the metadata files that will represent the various versions of the PLP out there ("WP7 and Silverlight" or "WP7 and Xbox" or "Just Xbox").

The simplest solution would be for Microsoft to give ECMA the binaries for the PLP so they become a standard, and we can reference and redistribute those libraries as part of Mono and Mono SDKs.

There are other advantages to contributing the PLP metadata profile to ECMA in addition to the redistribution, it would mean that ECMA would actually have a useful subset. The current subset that is standardized is a strange profile that is not really used in practice.
April 06, 2012 1:06
Bill/Daniel,
I've watched enough of the video to finally grok the issue here. You need changes in existing assemblies to do the type forwarding to handle the situations where types exist in different assemblies on different platforms. Without and update to older frameworks you can't do that, and updating those frameworks isn't without a whole set of problems.

BTW, I just realized that some of what I've been saying could have been misconstrued. I never thought there wasn't a reason behind why things are the way they are, I just didn't understand why. I'm also not complaining about the effort being made here. Far from it, I love what's happening. I'm just pointing out that we're in early days, still, and using portable libraries today isn't without some major pain points. It's not yet ready for wide adoption, and there's uncertainty as to when it will be. Tooling has to catch up, and it's not just VS11. AFAIK, Nuget also doesn't support portable libraries (would love to learn I'm wrong there, but there is an open issue on this topic, so I don't think I am).
April 06, 2012 1:44
I experimented with creating a portable class library for Json.NET but I found some APIs weren't available from the portal class library even when all the platforms that I had selected supported them.

Since I already a build script that happily compiles multiple versions for different platforms I've stuck with that.
April 06, 2012 1:57
James,

Since a lot of people use JSON.NET, we'd really love to have a portable version so that people can build portable libraries on top of it. We'd be interested in hearing which APIs caused issues for you, and we'd be happy to help you create a portable version.

There's various reasons APIs might not be usable from portable libraries, David gives a good summary of them in his MSDN article (under "Converting Existing Libraries to PCLs").
April 06, 2012 6:46
Taking into consideration the positive feedback (on the issues being resolved in Beta) I decided to refactor my http://SolrContrib.CodePlex.com (Composite application with Prism/Unity ports) and pulled out the MetroIOC and reinserted my Portable Class Library Unity port. I also pushed the Prism bits/pieces into a Portable Class Library. I've been programming to interfaces for the most part (in preparation for the real thing) so it was an easy swap but I did get bit in the butt on ICommand. Everything works (unit test/navigation) with the exception of button clicks :O I'm going to read the comments in this blog real close this weekend and see if there are any work-arounds before I pull the Prism bits out of the PCL into .Desktop and .Metro projects.
April 06, 2012 12:52
The Portable libraries are a great starting point, and binary portability is appealing, but it restricts you to using only a few Microsoft libraries that are supported as Portable in their entirety.

Building multiple projects and going for code portability rather than binary portability allows you to use the common features of classes that have different levels of support in different environments, so you can use more of the Microsoft libraries.

There's a trade-off in complexity, of course, and if Portable libraries provide enough functionality for you, then they'll be simpler and therefore better. In our case, though getting rid of our multiple projects sounded great, in practice we'd have to give up too much, and it's worth being aware that for a bit more overhead, if you need it, you can have more portability options than the Portable libraries can deliver.

One trick that we've found useful to avoid maintaining lots of linked files between projects (which seems to be the way most people do code portability) is to put all the projects in one folder, declare one the master project in which it's OK to add source files through the Visual Studio UI, and use wildcards in the MSBuild of the other projects to pick up all source files under a certain folder. All it takes to update the other projects is to reload them, rather than having to manually link every file. This method may have been superceded by the Project Linker, but we haven't had time to check that out thoroughly yet.
April 09, 2012 16:41
As suggested above the Portable Class Library (PCLs) issues encountered in the developer preview have all been resolved with the Beta release - I now have both a Unity and Prism port residing in PCLs. Blogged about Here
April 09, 2012 20:21
This massive blog post includes an explanation of how the Reactive Extensions team is migrating to a Portable Library: Reactive Extensions v2.0 Beta available now! - Towards a Portable Library world

Platform enlightenments explained
Making the core of Rx portable comes at a cost: the library can only rely on functionality in the intersection of all platforms targeted by the “Portable Library profile” we’re using.

...

To make this situation better, yet having a portable core, we added “platform enlightenments”. This innocent-looking System.Reactive.PlatformServices assembly plays a dual role. First of all, it provides platform-specific schedulers. Secondly, the (portable!) System.Reactive.Core assembly knows about its platform-dependent sibling and can check for its presence at runtime to get enlightened about the environment it’s running in.

...

Going forward, we’re engaging with the Portable Library BCL/CLR folks and the Windows Phone team to ensure an extended reach of our future portability story for Reactive Extensions.
Jed

Comments are closed.

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.