WP7 Async Data Access Pattern

One of the great things that I enjoy about Windows Phone 7 is the lengths Microsoft went to to make development easy and fun.  And of course, me being a .NET programmer by trade, getting to use .NET was pretty awesome too.  In my mind, Microsoft has done an excellent job communicating the ideas of the platform and the need to “control” the experience, in much the same way Apple does.  This “control” is necessary; mobile platforms do not, and cannot, offer the same freedom of expression we developers are used to in client apps and, in many ways, on the web.

One of the tight lines Microsoft has tried to walk over the years is the line that allows experienced programmers to use their knowledge and be creative while still providing the “protection” that keeps inexperienced devs from shooting themselves in the foot.  It is a difficult act to pull off, and Microsoft has been pretty good about getting it right, though rarely on their first try.

I came across something in Windows Phone 7 that really cramped my style recently.  The notion of forced asynchronous behavior in two areas.  Now, I have done a lot of programming in Android and I love their model.  Wrap your long running operation in AsyncTask.  This takes the operation off the UI thread thus mitigating the chance that OS will ask the user to kill the application (ANRing).

In Windows Phone 7 methods that are anticipated to be long running are async by default.  While this is good for novice programmers, it can make the OS seem inflexible in certain case.  For me this was mainly because the OS forces Web Requests to be Async.  My preferred approach would be to wrap a synchronous Web Request in a Background worker.  Since I can only this if I pass Action around, I decided to look for something different:

The Task

To start, I decided I was going to have to break apart the request from the processing since I knew I was not going to be able to make a web request synchronously, even if I wrapped it in a BackgroundWorker.  Thus I created the TaskBase serves as the base class for all tasks.  The centerpiece of this class is the Execute(Action) method, the source is shown below:

   1: /// 

   2: /// Perform the actual request

   3: /// 

   4: /// 

   5: public void ExecuteTask(Action<string> onRequestComplete)

   6: {

   7:     var request = new RestRequest(RequestUri, RequestMethod);

   8:     request.AddHeader("X-PayItSquare-AppKey", Config.AppKey);

   9:     if (RequiresAuthentication)

  10:         request.AddHeader("X-PayItSquare-Token",

  11:           CustomContext.Current.AuthToken);

  12:  

  13:     // add the parameters

  14:     foreach (var kv in _parameters)

  15:         request.AddParameter(kv.Key, kv.Value);

  16:  

  17:     // make the request

  18:     var client = new RestClient();

  19:     client.ExecuteAsync(request, response =>

  20:        onRequestComplete(response.Content));

  21: }

The idea here is that any task will result in a string being returned from the web request.  What the format of that string is, we do not care, it doesn’t matter.  (this code is using RestSharp library for the Rest request management)

The process of interpreting the string is the second part of the pattern.

Dependency Injection

I am not someone who believes Dependency Injection should be taboo on mobile devices.  Modern devices are extremely powerful and the applications we creating are becoming more complicated to the point where they can benefit from DI.  I use Ninject with my application to keep good separation and allow me to “design by contract”.

The Repository

I prefer to use the repository pattern to facilitate data persistence.  I can also use Ninject to inject various types of repositories each with the logic to parse the response string into whatever format.  For example, in Pay It Square I can load my repository using the following logic:

   1: /// 

   2: /// Loads the collect pages for the user into the repository

   3: /// 

   4: public void Load(string responseContent)

   5: {

   6:     XDocument document = XDocument.Parse(responseContent);

   7:     _collectPageList = (from xe in document.Root.Elements()

   8:                         select MakeCollectPage(xe)).ToList();

   9: }

With this pattern the purpose of the repository becomes clear. Interpret the response strings and return the appropriate information to the service layer to process the result.

This pattern’s purpose is to allow the Task execution to continue to be Async which is the one portion which is really the one portion that needs to be async.  Once the response string is generated the service and repository jump into action to parse and process the result.

Hope this helps some people when it comes to programming data centric applications in Windows Phone 7.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s