Monday, December 2, 2013

Building a cross platform solution for Windows Phone and Windows 8. Part I: Quick sharing of code

The intro to this series you can find here.

If you want to be able to quickly share things between a Windows Phone and Windows 8 application, you can always use the technique of linked files. Linked files are existing files you add to a project, for instance a file that already exists in your Windows 8 project and which you want to add to your Windows Phone project. But, instead of adding this existing file in the normal way, you add it as link. This is an additional option you can choose in the 'add existing item' dialog box.


This will give you this same file in your other project, but not as a copy. Meaning that if you make a change to the file in one of the two projects, you will see this change reflected in the other project as well.

You can use this technique for reusing code files or for reusing XAML files. But, as stated in the intro of this series, with XAML files you will have to:
  • remove any platform specific namespaces.
  • only reuse small pieces of XAML (you will for instance see that for pages the start tag in your XAML is different, for Windows Phone this is a PhoneApplicationPage, for Windows 8 this is a Page tag).
If you use the technique of linked files for sharing code files, you can additionally use partial classes to cope with any platform differences. The shared code you can put in a partial class that you add as a linked file for the other platform. You then add another partial class file (with the same class name of course) in each project with the platform specific stuff. If you don't like partial classes that much, you can also choose to use inheritance for this. You will add your base class as link and create child classes with platform specific code in them.

Another technique for coping with platform differences when using linked files is the use of preprocessor directives. These look like if-statements you put in between your code. They will contain the lines that are specific for a certain platform.

  public static void Initialize() 
  { 
#if WINDOWS_PHONE
      if (UIDispatcher != null) 
#else 
#if NETFX_CORE 
      if (UIDispatcher != null) 
#else 
      if (UIDispatcher != null && UIDispatcher.Thread.IsAlive) 
#endif 
#endif 
      { 
          return; 
      } 
#if NETFX_CORE 
      UIDispatcher = Window.Current.Dispatcher; 
#else 
#if WINDOWS_PHONE
      UIDispatcher = Deployment.Current.Dispatcher; 
#else 
      UIDispatcher = Dispatcher.CurrentDispatcher; 
#endif 
#endif 
  }

(The above code is courtesy of MVVMLight, a very good starter framework for doing MVVM).

As you can see in the above code snippet, there are some specific if-statements, called preprocessor directives, added. The ones for NETFX_CORE indicate to the compiler the lines of code that need to be compiled for Windows 8. The WINDOWS_PHONE ones will be compiled for Windows Phone. This can help you add platform specific code as well.

With the technique of linked files you can get quite some reuse of code between Windows Phone and Windows 8 applications. You can also use partial classes, inheritance or preprocessor directives to add platform specific code. But I do want to point out the following flaws in using this technique (and this is why I don't prefer using it myself):
  • Each technique (partial classes, inheritance, preprocessor directives) makes it hard to unit test your code, since it directly contains platform specific code.
  • Preprocessor directives, especially when used a lot, make it harder for you to read and understand your code (I've had projects going from a couple of preprocessor directives in one file to multiple and thus even more unreadable code).
In the following parts of this series, I will show you another technique for adding platform specific code, that will, at the same time, keep your code cleaner, more readable, more reusable and more maintainable (now, wouldn't that be nice).


Other parts in this series:

Part 0: Intro
Part I: Quick sharing of code
Part II: The class library approach
Part III: We need a pattern
Part IV: Mocking out the differences
Part V: Event to command
Part VI: Behaviors for coping with orientation changes
Part VII: Tombstoning

3 comments:

  1. Thanks. This series of articles is exactly what we need. Well written and interesting to read. Hope you will have a part related to the portable libraries.

    ReplyDelete
  2. That part just got published, so enjoy!

    ReplyDelete
  3. I've had a lot of trouble with linked resource files (resx). Other file types like code work fine, but not resources (at least for me). I had a Solution with one project that contained a resource file the other projects in the Solution linked to. The regeneration of the backing files became problematic, leading to strange results across the projects.

    ReplyDelete