Unit of Work and Silverlight "edge applications"

Unit of Work and Silverlight "edge applications"

Old forum URL: forums.lhotka.net/forums/t/11848.aspx


tiago posted on Tuesday, February 19, 2013

Hi Rocky,

First of all, let's make clear I'm referring to CSLA 4.3 concepts.

Reading USING CSLA4 eboks 2 & 3 (Objects and Data Access) I understand Unit of Work is a pattern used to simplify the use of async server communication. The problems it solves can show on any UI technology but are unavoidable for Silverlight and Windows Phone.

The problem this pattern solves is the need to load several objects for a given form and the fact that async server communication doesn't allow us to make sure every needed object is in place before we start rendering the form.

Since all server side DataPortal code runs synchronously, it's the server side DataPortal that makes sure every needed object was fetched from the database, before returning control to the client side. The server side DataPortal acts like a synchronizer (and makes life a lot easier).

The point concerns Silverlight applications that don't use the server side DataPortal but make the client side DataPortal use services - the kind of apps you described as «SOA “edge application” that is invoking services (SOAP or REST)». After several approaches I couldn't figure out how to use Unit of Work for those "Silverlight using services" applications.

The problem is that the synchronizer role is played by the SERVER side DataPortal and this kind of applications uses only the CLIENT side DataPortal.

On other kinds of applications, what we have is the server side DataPortal calling synchronous methods:

The fact is Silverligth client side DataPortal knows quite well DataPortal.BeginFetch() but doesn't know about DataPortal.Fetch(). So the Silverlight client side DataPortal only allows you to use asynchronous DataPortal calls.

On "Silverlight using services" applications we throw away the server side DataPortal and its synchronizer role is also thrown away. So, for this kind of applications, we can use Unit of Work if the the services (SOAP or REST) play that role by themselves.

Am I missing something?

JonnyBee replied on Wednesday, February 20, 2013

A UOW object is typically a ReadOnly object that fetch all the required objects before returning to the client. 

On a SL Edge application you can still use a ReadOnly object and in the asyncronous BeginFetch you can call chain several async serive calls to load all necessary objects before you call the async callback method to the UI (typically the controller).

The Microsoft.Bcl.Async package (in beta) allows you to use Task (async/await) in SL 4 and 5 applications with VS2012 and would simplify the local data access. See https://nuget.org/packages/Microsoft.Bcl.Async

tiago replied on Wednesday, February 20, 2013

Hi Jonny,

I'm referring to .NET 4.0/CSLA 4.3. So no async/awat etc. Of course I can chain several async calls but I have no way to wait until they are all finished before returning.

JonnyBee replied on Wednesday, February 20, 2013

If you use VS2012 and target .NET4/SL4/SL5 then you can use Async Targeting pack and async/await is available in your code. 

There is also Portable HttpClient for .NET Framework and Windows Phone coming from the Bcl team: http://blogs.msdn.com/b/bclteam/archive/2013/02/18/portable-httpclient-for-net-framework-and-windows-phone.aspx   that will support the following:

"This release of HttpClient adds support for the following platforms:

What does HttpClient do?

HttpClient is a part of .NET Framework 4.5 and Windows Store apps that provides developers an extremely easy way to connect with services across the internet including REST-based services. In fact, the methods exposed by HttpClient are the same verbs the HTTP protocol uses to communicate like GET/PUT/POST/DELETE.

In order to get some content from a web server say www.contoso.com we can write the following simple lines of code

HttpClient httpClient = new HttpClient();
string responseBodyAsText = await httpClient.GetStringAsync(“www.contoso.com”); 

…and get a response back from a web service. Obviously this is the simplest example, and the HttpClient library has many more feature and functions.

What do I need?

In order to use this release of HttpClient you need to ensure that you have two things.

Using HttpClient on .NET Framework 4.0 or Windows Phone 7.5

If you are writing a cross platform app targeting .Net 4.0 or the windows phone and write the code that you had written above you will get a compile error.

“Cannot await System.Threading.Task<HttpRequestMessage>”

This is because .Net 4.0 and Windows Phone 7.5 did not support the async/await keywords.In order to fix this add a reference to the Microsoft.Bcl.Async nuget package, which adds the support for Async and Await in down level platforms.To read more about this release go here."  

 

RockfordLhotka replied on Monday, February 25, 2013

In 4.3 (no async/await) you can solve this problem.

The pre-async/await Silverlight data portal requires that your DataPortal_XYZ methods (that run on the client) make a method call to tell the data portal when the method is complete.

Inside the DataPortal_XYZ method you can do as much async work as you desire, as long as you ensure that the complete method is only invoked when all the work is done.

Is this a pain? Yes, absolutely, because you typically need to orchestrate your async calls as a set of nested event handlers. Sadly that's the reality for any inter-related async calls in the pre-async/await Silverlight world.

You would be _far_ happier (I suspect) if you upgrade to CSLA 4.5 and use the Microsoft async targeting pack so you get the async/await keywords, and the newer and easier data portal behaviors.

In that case your DataPortal_XYZ method can be marked as async, and you can either await a series of async calls, or you can dispatch several and then wait for all the tasks to complete. This is a _lot_ simpler than the old-fashioned Silverlight eventing model.

To run serial requests:

private async Task DataPortal_Fetch(int id)
{
  await DoTheFirstThingAsync();
  await DoTheSecondThingAsync();
}

Or to run concurrent requests (from memory, so might not be quite right):

private async Task DataPortal_Fetch(int id)
{
  var task1 = DoTheFirstThingAsync();
  var task2 = DoTheSecondThingAsync();
  var taskList = new List<Task> { task1, task2 };
  Task.WaitAll(taskList);
}

 

ngm replied on Friday, February 22, 2013

 

Hello Tiago,

 

Here's my take on the Unit of Work (UoW) stereotype.

 

This type of object can be very handy. However, I look at it as a transporter for the other, usually well-defined objects. It's basically container that helps you bringing certain number and combination of objects back and forth.

There's one very big benefit that UoW brings in. That is, it frees you from very complex object compositions and therefore tighter coupling.

 

As far as UI goes, I would not relate UoW strictly to UI. There are a lot of other scenarios where it can be useful beyond UI. It’s true that it can be tricky to sync retrieval of all necessary objects for display of certain views, especially if that retrieval has to be done in parallel and if there are number of such objects. However, you want to think twice about UoW object’s granularity i.e. it’s much better to display one section of the view to user while the other one is still loading.

 

Speaking of asynchronous calls to Data Portal or its data access strategy, I think it has nothing to do with UoW concept. It’s totally up to you how and when you’re going to synchronize those asynchronous calls. On top of that, whether that asynchronity is implemented with Asynchronous Programming Model (BeginXXX, EndXXX, callbacks) or async/await it’s really implementation detail that’s not related to UoW in particular.

 

Let me give you a brief example, if UoW is used for presentation purposes, you might end up with two UoW objects: SongDetailsRetriever and SongImagesRetriever. The former would bring you let’s say AlbumAttributes and AuthorAttributes while the latter will retrieve CoverImages and UnofficialImages.

On the ViewModel you would issue two calls, which will start execution in parallel:

 

SongDetailsRetriever.Get SongDetailsRetriever(songId, songDetailsCallback);

SongImagesRetriever.GetSongImagesRetriever(songId, songImagesCallback);

 

You would probably want to update proper properties in ViewModel from songDetailsCallback with AlbumAttributes and AuthorAttributes objects that came via SongDetailsRetriever and thus give user feedback even if images didn't get back yet.

The moment songImagesCallback comes back; you would update adequate properties for CoverImages and UnofficialImages and give user even more visually appealing feedback.

If perhaps you want to prevent images coming first, you might want to suppress updating of ViewModel properties with CoverImages and UnofficialImages until songDetailsCallback gets invoked.

The other option is to chain the call to GetSongImagesRetriever from songDetailsCallback, but then you lose parallelism.

 

Speaking of local or remote Data Portal and service invocation data access, it really doesn’t matter. As long as your request to the Data Portal is executing on the worker thread you can consider the request relative to the worker as being synchronous i.e. request is not going to be completed until data access is finished, awaitable completed or your callback in there signals it.

All that is of your concern is that the callbacks are eventually going to be invoked signaling the completion and bringing the result back.

 

Hope this helps.

 

 - ngm

 

 

Copyright (c) Marimer LLC