Showing posts with label type. Show all posts
Showing posts with label type. Show all posts

Thursday, 9 May 2013

Type forwarding and XAML sharing between WP OS 7.1 and 8.0 projects

    This post is about a new feature available in Windows Phone OS 8.0 SDK called Type Forwarding.

    Have you ever wondered how does the Windows Phone 8.0 SDK handles the fact that the Panorama, Pivot controls changed the namespace and the assembly from OS 7.1 SDK to OS 8.0 SDK? (80% that you haven't :) ). I recently had to migrate an OS 7.1 project to OS 8.0, but also keep the old one (duplicated the old project and upgrade the duplicated one).

    Here is the story of what happens when you upgrade an OS 7.1 project that uses Panaroma or Pivot to OS 8.0:
    If you start a new Windows Phone Pivot App with the target OS 8.0 inside MainPage.xaml the prefix "phone" is used for the Pivot control where "phone" is:

 xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"  

    If, on the other hand, you create a new Windows Phone Pivot App with the target OS 7.1 inside MainPage.xaml the prefix "controls" is used for the Pivot/Panorama control where "controls" is:

 xmlns:controls="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls"  

    The real "magic" happens when you upgrade the Windows Phone 7.1 project to OS 8.0. The MainPage.xaml page doesn't change (you will still see the "controls" tag is kept in order to be able to better share the code between the versions), but instead a reference to Microsoft.Phone.Controls.dll is added to the OS 8.0 reference that is not used if you create a new project with target OS 8.0. If you wonder if by adding this reference you use the old version of the controls the answer is NO. What this assembly does is that is uses a really neat and new  feature of the .Net compiler called Type Forwarding. This feature can be used when you move a class from one namespace/dll (assembly) to another and you don't want to recompile the application to reference the new dll but you will only deploy the two dlls where the first one (the one that the application already knew uses the Type Forwarding to tell the application that a certain class/es moved to another assembly). In the case of Windows Phone OS 8.0 SDK the usage is even "cooler" as it enables you to use the same XAML for both OS 7.1 projects and OS 8.0 ones. Inside AssemblyInfo.cs of Microsoft.Phone.Controls.dll OS 8.0 version we have all the declarations needed to forward the types to their new locations:

 [assembly: TypeForwardedTo(typeof(Panorama))]  
[assembly: TypeForwardedTo(typeof(PanoramaItem))]
[assembly: TypeForwardedTo(typeof(Pivot))]
[assembly: TypeForwardedTo(typeof(PivotItem))]
[assembly: TypeForwardedTo(typeof(PivotItemEventArgs))]
[assembly: TypeForwardedTo(typeof(AnimationDirection))]
[assembly: TypeForwardedTo(typeof(PanningBackgroundLayer))]
[assembly: TypeForwardedTo(typeof(PanningLayer))]
[assembly: TypeForwardedTo(typeof(PanningTitleLayer))]
[assembly: TypeForwardedTo(typeof(PanoramaPanel))]
[assembly: TypeForwardedTo(typeof(PivotHeaderItem))]
[assembly: TypeForwardedTo(typeof(PivotHeadersControl))]

I am attaching a small project called TypeForwarding that implements the same functionality as Microsoft.Phone.Controls.dll OS 8.0 version.

Other usages that I can thing of:

  • Flurry SDK changes the name of the namespace for the Api class for WP7SDK to WP8SDK (bad choice when you need code sharing). If you want to keep the same code for the OS 7.1 and the OS 8.0 version of the app you will have to use conditional compiling for every file where you use the Api class. Much easier would be to create an OS 8.0 library project with the default namespace WP7SDK and forward the Api class to the WP8SDK added as a reference to the library project. This way the old WP7SDK will continue to work as it was on the OS 8.0 using the OS 8.0 version of the Flurry SDK.
  • MVVM Light. If you use inside your XAML the EventToCommand this is not xaml shareable between OS 7.1 and OS 8.0 because the assemblies changes from GalaSoft.MvvmLight.Extras.WP71.dll to GalaSoft.MvvmLight.Extras.WP8.dll. The easiest approach in this case (an open source) would be to recompile the dll and use the same name for both versions of the dll. But if you don't have access to the source code of the dll you could use type forwarding.  Also a third approach would be to derive your on class like MyEventToCommand and use this inside the xaml.
Keep in mind this neat feature because you might need it. I would also love to see, in the next version of the SDK, the possibility to use MarkupExtension this way we could conditionally compile parts of the XAML depending on the version of the SDK the app is running on. Have a look at this blog post that explains how it works on WPF projects.



Till next post NAMASTE and have fun coding for Windows Phone!

Sunday, 30 December 2012

Detect CPU architecture at runtime for Windows 8 Store Apps

  If you are developing an application for the Windows 8 Store it is very important that you test it on an ARM device (Surface RT, Asus VivoTab RT, Dell XPS 10,etc.) before sending it into certification. You will probably have some bad surprises and not everything that was fast&fluid on your development machine will continue to be so on an ARM device (the list scroll performance reminds me of the first version of Windows Phone). So you will have to simplify the layouts, animations and in some cases even rewrite part of your code. Parallel Programming is your friend if you can use it (for Kids' Orchestra I had the big problem that generating 100ms of sound output took more then 100ms so after 2 days of trying to optimize the C# source code I realized that I only had to use the Parallel.For and everything started working). 
   Due to performance differences you might need to split the user experience/code on different architectures (like disabling some animations on ARM). If this is the case it becomes very important to know the processor architecture on which your application runs. One solution would be to create 3 different packages of your applications and use the conditional compilation to differentiate between what happens on each architecture. If you still want to use only one package (Any CPU) it is enough to have a method that returns the processor architecture.
    The bad news is that WinRT framework doesn't have any method/property that returns the processor architecture  (at least I don't know it). The good news is that you can still use GetNativeSystemInfo as it is an api supported for Windows Store apps (it is even supported for Windows Phone 8 apps):


  For Windows Store apps you can use two approaches to call this api:
1. Use P/Invoke -this is the one I opted for;
2. Create a Windows Runtime Component in C++ that you can then call from managed code - this is the approach you will have to use if you need to call this function on Windows Phone 8.

   What I did is to create a public class, which I called CPU, and has one public static property NativeInfo that returns an SystemInfo object:

 public class SystemInfo  
{
public ProcessorArchitecture ProcessorArchitecture;
public ushort ProcessorArchitectureId;
public ProcessorType ProcessorType;
public uint ProcessorTypeId;
public uint NumberOfProcessors;
public ushort ProcessorLevel;
public ushort ProcessorRevision;
public uint AllocationGranularity;
};

and a public method IsProcessorFeaturePresent (invoking also a supported Api for Windows Store applications) which returns if a certain ProcessorFeature feature is supported or not.

I have also created a small sample that will give you a list with your processor details. Here is the result I got on  my Surface:


Hope you will find the class useful. Don't hesitate to contact me if you need further details.

SOURCE CODE:

NAMASTE!