Multi-Targeting: Using an Azure Cloud WCF Service for Desktop, Silverlight and Windows Phone 7

Note: To successfully share the same code (consuming the WCF Azure web service), on the Desktop platform you must "Add Service Reference", click Advanced and ensure "Generate asynchronous operations" is checked; asynchronous is the default for Silverlight and Phone when you Add Service Reference to these projects.

What I am most impressed with is the performance of the Azure Web Service.  When I access the link it displays immediately; I'm accustomed to "spin-up" time which has successive access generally fast, but I have never seen this kind of performance accessing a web service! 

Most of us are using Rest services (which are very convenient) but in the case of my http://passwordmgr.codeplex.com/ project I am going the WCF road for performance reasons;  I want the Phone access to be extremely fast without any additional overhead.   Anyone who has created enterprise level applications using WCF services understands the ramifications of this (you have to update any Web References if the interface changes), however since I'm using dependency injection and a data access layer my enterprise application configuration carries very little overhead (as I will demonstrate below).

Setup was only hard because of the dis-information and outdated data that is available when Binging the topic on adding WCF services (particularly for Windows Phone).   The following is an updated process as of 2/20/2011.

Creating the service

  1. Add new project - select Cloud
  2. Select Windows Azure Project [OK]
  3. Select WCF Service Web Role [OK]
    • It will create two projects, a Web Role and an Azure cloud application
  4. I renamed the WCFServiceWebRole1 to WCFGwnServiceWebRole, this caused me some issues because I was permitted to successfully launch the web role service directly but once deployed the Azure cloud application would not run,  I had to turn on CustomErrors to find out that the rename didn't rename the GwnService.svc class definition (line 4 on the bottom right pane in the image below); once I fixed this the application warned me that I should have 2 instances - I made the change on line 4 of the top right pane in image below. 

Publishing the service

This was more challenging then it needed to be  perhaps these steps will save you a few hours.  

Create Certificate

  1. Right click on the Azure project (not the Web Role) and select Deploy your Windows Azure project to Windows Azure.
  2. Click Credentials dropdown list and select Add
  3. Click dropdown list for option 1 (Create or select an existing...) and select <create> and provide a name [OK]
  4. Select the link on option 2 to Copy the full path
  5. Click on link to launch Windows Azure Portal
  6. Select Hosted Services, Storage Accounts & CDN
  7. Select Manage Certificates
  8. Click Add Certificate
  9. Click [Browse] and paste the certificate path and click [Done]
  10. Cancel the Visual Studio model windows to return to Visual Studio.

Deploy your Service

  1. Right click on the Azure project (not the Web Role) and select Publish
  2. I attempted to add a credential but this sent me into a chicken-before-the-egg corner and after I configured the necessary pieces it could not connect to the allocated storage.   It is EASIEST if you click the Create Service Package Only radio button and [OK].   
    • An explorer window will open that will contain the Service package, copy the path to the clipboard
    • Go to the Windows Azure portal https://windows.azure.com/
    • Create a Storage Account - you'll need this to publish

    • Click on Hosted Services in left menu
    • Click on New Staging Deployment in top menu
    • Provide a Deployment name
    • Click [Browse Locally] and paste the path previously saved folder path from the clipboard to select both the Package location and Configuration file.   Click [OK] and have patience while it imports and deploys the package to your staging area 

At any point after publishing you can click on Hosted Services, select your service and then get the DNS name as shown below - simply add your service name to the end.   Note: this name will change everytime you publish which is why configuration needs to be simplified (using dependency injection as shown below)

After the initial publish, successive publishes will be simple - simply right click on the Azure project and pick the Credential configured for this solution and click [OK]

Consuming the newly published Web Service

The following is the test data access layer I created for the Desktop, Silverlight and Windows Phone applications (they all share this code).   I added a Web Service Reference being sure to use the same name.

When I got done adding the phone's web reference the auto generated ServiceReferences.ClientConfig was empty (only had a single line for configuration).   I found I had to reinstall the Silverlight4_tools.exe and all was well after that.    I added Web References to the Silverlight and Desktop applications (changeset 85264 on http://PasswordMgr.CodePlex.com).   I plugged in a hook that executes GetData() during the ReadList() command for the Password Manager IF the AppConfig.ServiceAddress is not null (AppConfig is injected in class base via dependency injection).

I had to republish a few times because of the web role rename issue and each time the address changed.  To simplify matters I updated the bootstrapper (single location shared by all of the applications in the main app projects) so that it configured the address from a single location (line 134 below); this is the only change I have to make because I programmatically configure the binding and address (lines 24-29 above).  With this technique configuration files are no longer required - all I'll have to do is update web references for my data access layer project(s) if the interface changes and I'll be done. 

IMPORTANT: because I inject the value into an IAppConfig singleton (line 133 below) it is available throughout the entire application (ClassBase has the unity dependency property IAppConfig, line 13 above, so it is easily available to my data acess layer). 

Note: I remarked out line 133 in the changeset because odds are the address will change again and I don't want to introduce a bug that will crash the app for those that might download the source code.

With the above noted configurations I was able to successfully launch and run the Desktop and Phone application and watch the output log display that the contents were successfully returned.   Silverlight gave an "attempting to access a service in a cross domain way" error which I resolved by adding a ClientAccessPolicy.xml file per the following LINK.    With that change, and redeploying the web service, all three platforms successfully ran the code.

 


Tags: ,
Categories: Azure


Actions: E-mail | Permalink |  Grammar/Typo/Better way? Please let me know

Multi-Targeting: Sharing XAML Code between platforms / Programmatically loading resources

Below I show the output from both the Desktop (top) and Silverlight (bottom) applications for the open source Password Manager project  http://PasswordMgr.CodePlex.com  (changeset 84433); I am now sharing the XAML code as well as all source code for the Security Module. 

Note: the password manager project has a "single" codebase that is shared between the Windows Phone, Desktop and Silverlight applications. 
 

 320 Note in the left image how all of our Views are linked files - these are linked to the Silverlight project.  All of the other files are linked to the Phone project.   The only code for this project that is not linked is the resource files (see arrow); the resources will manage differences between platforms. 

Since our linked projects have the same namespace, it makes it relatively easy to share the same user control 

Where it became challenging was sharing XAML that required resources and used a baseclass that resided in a separate project, e.g., the following XML file can't be shared because it has a reference to Silverlight assembly (line 6 top pane) so that it can use the UserControlBase in the Gwn.Infrastructure.xxxx project.

The solution was to create a UserControlBase in the "current" project and have it derive from the UserControlBase - reference middle pane.

With that done I was able to make the necessary reference (line 6 in the bottom pane of the image above) in a manner that will allow me to link (share) this XAML with the Desktop application. 

The Gwn.Infratructure.Base.UserControlBase class has conditional compiler statements that will pull in the applicable Resource file for the platform being executed.  This proves very useful because with a single declaration all of our UserControls (derived from UserControlBase) will have access to all of the resources, i.e., Styles, Templates, Converters, etc.

Below (top pane) we show the _Shared.Generic.xaml file which loads our other resources.   Each of the resources will reference the Common.Generic.xaml which will have the global colors used throughout the system for the various styles and templates. 

Likewise it serves as a great convenience to have all of the converters available, while preventing the need to reference these external resources in XAML.   We've reduced the declaration requirements in each of our XAML files while providing them all of the resources available.

 Source code available at: http://PasswordMgr.CodePlex.com 


Tags: ,
Categories:


Actions: E-mail | Permalink |  Grammar/Typo/Better way? Please let me know

Prism / Dependency Injection for Windows Phone 7

If you are looking for Prism functionality for Windows Phone 7 you may want to visit our open source Password Manager application on CodePlex (http://PasswordMgr.CodePlex.com).

The objective of porting Prism to Windows Phone 7 was to provide a platform that can be used identically on Desktop, Silverlight and Windows Phone 7 operating systems so that I could have a single code base using the Project Linker (May 2010).   Since Prism is available for both Desktop and Silverlight all I had to be concerned with was  Windows Phone 7.   The Prism for Windows Phone RC on CodePlex lacked Dependency Injection support and only provided a few classes - this was not going to do for our purposes.

Important note: Our primary goal is to create a single code base that supports multiple platforms.  Our efforts with porting Prism 4 and Unity to the phone platform will be limited to this objective; we will not be investing time/energy into building up the Unity feature set beyond our needs as this time is needed to complete the framework and Password Manager application.

A key component that I was missing was Unity, a Dependency Injection (DI) container that Prism 4 is designed to work with (as well as MEF).  Without this DI container there would be no port (MEF is not supported on both Silverlight and WP7 so this was not an option).  Since the latest word on Unity for WP7 was "there would be no port" I had to improvise.  I grabbed the Container Model, DI container, from the Mobile Application Blocks and imported it into my Gwn.ContainerModel.Mobile (WP7 project). 

Unit Testing

It was time to roll up my sleeves and port over all of the Prism and Container Model unit test, this posed a unique problems since I needed the test to run against the Windows Phone 7 code, not the desktop code.   My solution is shown in Fig 1. below:

  1. I copied Prism.Desktop files into Gwn.Prism4.Mobile (two left panes below)
  2. I copied Prism.UnityExtensions.Desktop into Gwn.Prism4.Mobile\UnityExtensions folder so I didn't have to manage two projects.
  3. I created a Gwn.Prism4.Desktop project that was linked to the Gwn.Prism4.Mobile project (two middle panes below).
  4. I created my Gwn.Prism4.Desktop.Tests and pointed it to my linked code in Gwn.Prism4.Desktop (code resides in Gwn.Prism4.Mobile).
  5. I followed the same steps for the Gwn.ContainerModel.Desktop.Tests

I was starting this port under the notion "if it compiles, it will run".

Emulating Unity with the ContainerModel

Getting Prism 4 to compile required us to provide components it needed, such as ObjectBuilder2, ServiceLocation and Unity classes. As the compiler complained I would pull the classes from the applicable source and place it in a folder, within the Gwn.ContainerModel.Mobile project, that corresponded with the namespace. When the smoke settled I was pleasantly surprised that most of the Prism 4 framework remained and compiled successfully.

There were some component methods, such as RemoveAll() in the image below, that I had to create because they didn't exist in the .Net WP7 environment. Since the unit test were running against the ported code I had a reasonable amount of confidence that if the unit test passed that my manual updates were successful.

 As of changeset 81886, of the Password Manager on CodePlex, there are 727 test that successfully pass against the original Prism4/ContainerModel test fixtures.   As is the goal with Test Driven Development (TDD) I had a lot of failing test that I needed to make work.   Most of the test revolved around the Unity container; up to this point I was only concerned with getting it to compile so along the way I created a UnityContainer class (that implements IUnityContainer) which had a lot of empty methods that simply threw exceptions.   You'll find that there are still empty methods in the UnityContainer because I only concerned myself with the methods that were required to pass the unit test.

I started by instantiating the ContainerModel DI container on line 11 (which was passing all of it's unit test) and then updated each called method to utilize the _container class.    I then had to update each failing method to perform the functionality that was required to successfully pass the test (reference RegisterType method below).

Along the way I found there were a number of null references because the ContainerModel DI container does not support constructor injection.  This required me to update each Prism 4 class that relied on constructor injection to ensure each constructor parameter was supported with setter injection;  I moved each parameter into a property with a [Dependency] attribute above it.   I then had to update the Resolve methods to ensure that as each class was resolved that it performed a BuildUp() which ensured its properties, marked with the DependencyAttribute, were initialized.


Tags: , ,
Categories:


Actions: E-mail | Permalink |  Grammar/Typo/Better way? Please let me know

Sqlite for Windows Phone 7 (Desktop and Silverlight)

If you are looking for a SQL Database for your Windows Phone you may want to visit our Password Manager open source project on CodePlex (http://PasswordMgr.CodePlex.com).   We modified Dan Ardelean's Sqlite prototype (he ported CSharp-Sqlite by Noah Hart to Phone) so that it is supported consistently on all three platforms (Phone, Desktop and Silverlight) w/unit test as shown in the images below.

To make it easier to work with we created a SqliteDataProvider - below we show it being used in the FixtureBase (unit test baseclass) to create test tables.

The actual code (for all libraries) reside in the .Phone projects.  All other projects, to include test projects,  "Link" to the .Phone projects.  The assumption with the Unit Test is that if it will compile on the .Phone platform, it will run consistently with the other platforms since they are the same exact code (with minor platform modifications).  Below is the Unit Test used for TDD of the SqliteDataProvider:


Tags: ,
Categories:


Actions: E-mail | Permalink |  Grammar/Typo/Better way? Please let me know