Archive

Posts Tagged ‘PCL’

Thoughts on PCLs (Portable Class Libraries)

June 4, 2013 1 comment

I’m working with a number of partners right now that want to target both Windows Phone and Windows 8 using a single codebase. This post is a copy of an e-mail I send to them when they’re getting ready to start development using Portable Class Libraries.

First, I’d like to share some libraries that I’ve found to be invaluable during PCL development:

 

HttpClient for PCL

http://blogs.msdn.com/b/bclteam/archive/2013/02/18/portable-httpclient-for-net-framework-and-windows-phone.aspx

Windows 8 has the most advanced client for reading data from the web asynchronously. That client is called HttpClient. Unfortunately HttpClient doesn’t exist on Windows Phone, so the moment you check the box to include Windows Phone support in your PCL you lose the ability to leverage HttpClient and have to use the older WebClient. This library adds the awesome tool back into your PCL project.

 

MVVM Light PCL

http://nuget.org/packages/Portable.MvvmLightLibs

MVVM Light is one of the most popular libraries for implementing the MVVM pattern on Windows Phone and Windows 8. Until recently they had one library for Windows Phone and another library for Windows 8. This made it impossible to create ViewModels in a PCL project. Now that they have a PCL library you can create all of your ViewModels in PCL and use them on both platforms. The only trick is make sure you reference the PCL version of this library in you Windows Phone and Windows 8 projects as well (not the platform-specific versions).

 

 

Finally, are PCLs the right approach for your project? Though I’m a fan of PCLs, I have found there are times when it takes more effort to work around the limitations of PCL than it does to just share (link) code across projects.

 

For example, let’s say you want to remember a setting between application runs. On Windows Phone you use a class called IsolatedStorageSettings and on Windows 8 you use ApplicationData.Current.LocalSettings. If you wanted to abstract this difference in a PCL you would have to create an interface (let’s call it ISettingManager) and inject that interface from the host application down into the PCL when the application starts up. This is called "Dependency Injection" and you can read more about this approach in Portable Class Libraries: A Primer.

 

Although dependency injection absolutely will solve this problem, it’s also somewhat complicated to implement. You have to define the interface, create two platform-specific implementations of the interface (one for WP and one for Win8) and then you have to remember to pass the implementation into the PCL on application start. It’s not rocket science, but it is a lot of effort to solve for such a minor difference.

 

Another approach is to link a .CS file into both projects and take advantage of conditional compile statements. Here’s a short article on conditional compilation in Visual Studio.

 

With this approach we could easily write the following class and use it in both projects:

 

static public class SettingManager

{

    static public void SetValue(string name, string value)

    {

        #if WIN_RT

            var settings = ApplicationData.Current.LocalSettings;

            settings.Values[name] = value;

        #elif WINDOWS_PHONE

            var settings = IsolatedStorageSettings.ApplicationSettings;

            settings[name] = value;

        #endif

    }

 

    static public string GetValue(string name)

    {

        #if WIN_RT

            var settings = ApplicationData.Current.LocalSettings;

            return (string)settings.Values[name];

        #elif WINDOWS_PHONE

            var settings = IsolatedStorageSettings.ApplicationSettings;

            return (string)settings[name];

        #endif

    }

}

 

Notice that the compiler takes care of including the right lines of code for each platform. In my opinion this is a lot simpler than creating interfaces and dealing with dependency injection. However, if PCLs make sense for your project using shared files and conditional compilation can be very helpful when creating the interface implementations (wrappers).