How the Presentation Model could look like when using Silverlight 2.0 (Part 2)

In my previous post I wrote about how the Presentation Model could be implemented within Silverlight 2.0, in this post I will show how we can use Async. calls to Web Services.

To make it possible to handle Async. calls from a Repository on the client side, we need to make sure we can specify a callback method which should be called when the Async. operation is completed. I decided to create a new EventArgument called AsyncCallCompletedEventArgs:

public class AsyncCallCompletedEventArgs<T> : EventArgs
{
    public T Result { get; set; }
}


public class AsyncCallCompletedEventArgs : EventArgs
{
}

 

I have created two version of the AsyncCallCompletedEventArgs class, one which returns a Result, and one which will not return anything at the moment. The last on can be used for operations like Save or Delete etc, where we don’t need to return a Result. Some other properties we could have added to the new EventArgs are Cancelled and Error etc. But I will make this example short and only use it as basic demonstration.

The interface of the Repository on the client side need to be updated for async. calls. Here is the new version of the INameRepository interface:

public interface INameRepository
{
    void GetNameAsync(EventHandler<AsyncCallCompletedEventArgs<NameEntity>> callback);

    void SaveNameAsync(NameEntity name, EventHandler<AsyncCallCompletedEventArgs> callback);
}


Note: I use the EventHandler delegate here, but I could have skipped it and created my own one that may be more suitable for what I want to do,

The NameRepository is updated to make a call to a WCF service asynchronous, and will make a call to a callback method passed as an argument to the Repositories methods, when the WCF service are completed.

public class NameRepository : INameRepository
{
    public void GetNameAsync(EventHandler<AsyncCallCompletedEventArgs<NameEntity>> callback)
    {
        if (callback == null)
           throw new ArgumentNullException("callback");

        var nameServiceClient = new NameServiceClient();

        nameServiceClient.GetCompleted += nameServiceClient_GetCompleted;
        nameServiceClient.GetAsync(callback);
    }

       
    void nameServiceClient_GetCompleted(object sender, GetCompletedEventArgs e)
    {
        var callback = e.UserState as EventHandler<AsyncCallCompletedEventArgs<NameEntity>>;

        if (callback == null)
           throw new ArgumentException("No callback is specified or are of wrong type");

        callback(this, new AsyncCallCompletedEventArgs<NameEntity>()
                                       {
                                           Result = new NameEntity() { Name = e.Result }
                                       });
    }

       
    public void SaveNameAsync(NameEntity name, EventHandler<AsyncCallCompletedEventArgs> callback)
    {
       if (name == null)
          throw new ArgumentNullException("name");

       if (callback == null)
          throw new ArgumentNullException("callback");

       var nameServiceClient = new NameServiceClient();

       nameServiceClient.SaveCompleted += nameServiceClient_SaveCompleted;
       nameServiceClient.SaveAsync(name.Name, callback);
    }


    void nameServiceClient_SaveCompleted(object sender, AsyncCompletedEventArgs e)
    {
       var callback = e.UserState as EventHandler<AsyncCallCompletedEventArgs>;

       if (callback == null)
          throw new ArgumentException("No callback is specified or are of wrong type");

       callback(this, new AsyncCallCompletedEventArgs());
    }
}

When I make a call to the WCF Service GetAsync method, I pass the callback as an argument to the GetAsync method, so the callback is passed as a UserState. From the GetCompleted event, I can get the callback from the AsyncCompletedEventArgs UserState property.

Now when the Repository is updated to suppert Async calls and also take a callback as an argument (I could have added Completed events to the Repository, but I prefer to pass a callback as an argument), the Presentation Model must be updated. I decided to rename the Load and Save method to LoadAsync and SaveAsync, only to make sure the user of the code, will know that a Async. call will be done when they call the methods. Here is the new version of the Load and Save method of the NamePresentationModel class:

public void LoadAsync(EventHandler<AsyncCallCompletedEventArgs<NamePresentationModel>> callback)
{
   if (callback == null)
      throw new ArgumentNullException("callback");

    _nameRepository.GetNameAsync((sender, args) => 
             {
                  _nameEntity = args.Result;

                  callback(this, new AsyncCallCompletedEventArgs<NamePresentationModel>() { Result = this });
              });
}


public void SaveAsync(EventHandler<AsyncCallCompletedEventArgs> callback)
{
   _nameRepository.SaveNameAsync(_nameEntity, callback);
}


Note: I have only changed the Load and Save method from the previous post.

Now when the Presentation Model also support Async. calls we need to do a final update to the code behind file “Page.xaml.cs”. The code behind fill will pass a callback to the Presentation Model’s SaveAsync and LoadAsync method, the callback methods will be executed when the WCF service returns a value from the server.

private void Button_Click(object sender, RoutedEventArgs e)
{
    _namePresentationModel.SaveAsync((source, args) =>
                                    {
                                       messageTextBlock.Text = "NameEntity Saved";
                                    });
}


private void LoadFromPresentationModel()
{
    _namePresentationModel.LoadAsync((sender, args) =>
                                     {
                                          myStackPanel.DataContext = args.Result;
                                     });
}


This is one way to make sure we can handle Async. calls, I decided to use a callback method instead of a Completed event, but we could simply use a Completed event for the Async. operations if we wants to, but I like the way to pass a anonymous delegate to the SaveAsync and LoadAsync method as you can see in the last code above.

Published Monday, February 16, 2009 11:27 AM by Fredrik N

Comments

# re: How the Presentation Model could look like when using Silverlight 2.0 (Part 2)

Monday, February 16, 2009 1:25 PM by Torkel

I am not sure what this has to do with presentation model, looks more like how do async WCF calls to the server. Not that it isn't useful post :)

Have you checked out caliburn? Very nice framework for WPF and Silverlight, allows you to move handling ui events in a ui-agnostic way directly in the presentation model (that can then be made non-anemic).

www.codinginstinct.com/.../wpf-action-dispatch-with-caliburn.html

www.codeplex.com/caliburn

# re: How the Presentation Model could look like when using Silverlight 2.0 (Part 2)

Monday, February 16, 2009 1:57 PM by Fredrik N

@Torkel:

You need to read my prev. post about one way to implement PM. This is only part 2 where a reader wanted to know how to handle WCF calls which is async..

# re: How the Presentation Model could look like when using Silverlight 2.0 (Part 2)

Tuesday, February 17, 2009 12:37 AM by Kunal Shetye

Thanks for the part 2 Fredrik :)

# How the Presentation Model could look like when using Silverlight 2.0 (Part 3)

Sunday, February 22, 2009 8:15 AM by Fredrik Normén

In my previous Part 1 and Part 2 I wrote how a Presentation Model could be implemented and how to handle

# How the Presentation Model could look like when using Silverlight 2.0 (Part 3)

Sunday, February 22, 2009 8:23 AM by Cornerstones utvecklarblogg

In my previous Part 1 and Part 2 I wrote how a Presentation Model could be implemented and how to handle

# How the Presentation Model could look like when using Silverlight 2.0 (Part 3)

Sunday, February 22, 2009 10:17 AM by ASPInsiders

In my previous Part 1 and Part 2 I wrote how a Presentation Model could be implemented and how to handle

# Silverlight Cream for February 23, 2009 -- #526

Monday, February 23, 2009 7:28 PM by Community Blogs

In this issue: Fredrik Normén(2), Timmy Kokke, Shemesh, Manish Dalal, Terence Tsang, Michael S. Scherotter

# Silverlight Travel &raquo; How the Presentation Model could look like when using Silverlight (Part 2)

Pingback from  Silverlight Travel &raquo; How the Presentation Model could look like when using Silverlight (Part 2)

# How the Presentation Model could look like when using Silverlight 2.0 &laquo; vincenthome&#8217;s Tech Clips

Pingback from  How the Presentation Model could look like when using Silverlight 2.0 &laquo; vincenthome&#8217;s Tech Clips

Leave a Comment

(required) 
(required) 
(optional)
(required)