Wednesday, December 21, 2011

Mango Sample: Portable Assemblies

The Problem

Many developers and organizations have existing libraries (assemblies) used in their desktop solutions. Object Oriented (OOP) Developers love to reuse existing assets. However, desktop assemblies may not be reused in Silverlight projects. Only Silverlight assemblies may be referenced by Silverlight projects.

To include a class library, for example, it must be compiled specifically for Silverlight. Because Silverlight is an abbreviation of the .Net Framework, a simple recompile is not always possible.

The Explanation

The .Net framework has two key ingredients. First, the Framework Class Library (FCL). This contains base classes, interfaces, value types, and most of the Framework’s namespaces. However, there’s also the Base Class Library (BLC). This contains the Framework’s fundamental data types and shared functions.

MSDN: Silverlight makes it easier for developers to build [rich] applications, because it overcomes many of the incompatibilities of current technologies, and provides within one platform the tools to create rich, cross-platform, integrated applications.

Silverlight’s runtime is the CoreCLR. This is a reduced version of the desktop CLR – addressing multiple platforms and a reduced download size. The CoreCLR is implemented through the Platform Abstraction Layer (PAL), which gives Silverlight its cross-platform support. This is also the cause of the framework incompatibilities.

Since non-Windows platforms (like the Macintosh and Windows Phone) cannot support features Windows-specific (like WMI, System.Console, etc.), Silverlight’s CoreCLR and libraries do not contain them. Silverlight is a subset of the desktop framework – it is , basically, different. As a result, assemblies not compiled to Silverlight are incompatible with the desktop.

Solution 1: Code Generation

If you are not already using Code Generation in your projects (especially your large projects) you are likely typing more code than you need to. Code generation is great – reducing errors and increasing velocity.

Have you ever added a service reference to a project? Where does all that proxy code comes from? Visual Studio has a code generation tool, called T4 templates, built-in. We talk about T4 far too little! T4 allows you to generate code at design-time and build-time, based on a model.

Note: I have used CodeSmith many times. It is fantastic. However, I have used T4 templates 100% for the past two years. The generation tool really does not matter.

I have written an article on using T4 templates with Entity Framework. Doing so lets you define your models in a separate assembly that can be shared by both the server (WCF) and the client (WPF). Additionally, the same T4 could be used to create an identical, separate assembly intended to be be referenced in Silverlight projects.

Here’s an example of a DTO:

In the code above, see the ToString() method? That is custom. When you add a service reference to your client, a proxy-version of the User class is created for you. This is inferior. The proxy version will not have ToString(). Proxy classes only have properties.

See the image above? To get all the functionality in your models in every tier, you must share the defining assembly – a separate assembly. That means your models must be compiled in such a way that they can be referenced in both places.

In WPF this is simple. The models can be compiled to the desktop framework on the server and client. For Windows Phone (which is a Silverlight client), the server’s desktop framework will not work. Introducing a Silverlight version of models to the server is also incorrect.

So, how is Code Generation a solution?

It is a model-specific solution. Since the framework is different between the desktop and client, additional implementations (i.e.: methods) must be written with care. Code Generation does not solve that. Code Generation just writes identical models in a separate project for you.

Solution 2: Linked Files

When you add a file to a project, you can either save the file to the project's folder, or you can to the project.

When you add an existing file to a project, the default option is to copy the file to the folder where your current project resides. If you want to instead link to the file (rather than actually moving the file to that folder) you can do so.

So, how are Linked Files a solution?

Like Solution 1, this is a model-specific solution. Linked Files results in a single file being shared between multiple projects. If you are careful to keep your namespaces consistent, then your models can be created in one location and used somewhere else – giving you the same reuse across tiers.

Solution 3: Portable Class Library

In the image above, I am using the Extension Manager to locate and install the Portable Library Tools. Installing this extension will give you an additional project called the Portable Class Library (PCL).

In the image above, I am adding a new project to my solution. I have located the Portable Class Library – which is made available through the Portable Library Tools extension.

So, how is the PCL a solution?

Unlike Solution 1 and Solution 2, the PCL is the lowest common denominator across all Microsoft platforms:

Windows Desktop

Silverlight

Windows Phone

Xbox

The PCL is 100% compatible across platforms. You have just one assembly now! Congratulations.

This is Nirvana?

Sort of. Remember this is the lowest common denominator – that’s what makes it portable. The code that you include will be restricted in some ways – ways that might require yet another companion assembly.

This may not bother you and it might server you perfectly. Tick the Nirvana box!

If the restrictions are unbearable to you (or your team or your architect), Solutions 1 or 2 might prove to be altogether better for you. I can see that being very legitimate.

Isn’t it nice to have choices?

Conclusion

Sharing assets between different frameworks is impossible, sort of. Consider the three options in this article. They can provide to you the real fidelity of rich models without having to jump too many hoops.

As a Windows Phone developer, leveraging existing assets can make your application rich without requiring a considerable amount of additional coding. With the incompatibilities between Silverlight and the desktop you might have thought that was just a dream. Now, you have real options.

Hey! I'm Jerry Nixon, a Microsoft Engineer in Colorado. If you are into development, you are at the right place. I blog, I teach, and speak; should you see me out somewhere, say hi! Thanks for your visit.