Silverlight: Prefer synchronous web service calls

Andreas Hallberg

Daniel Vaughan realized that synchronous web service calls are perfectly legal in Silverlight as long as the calls are not made on the UI thread. He wrote a neat library on CodeProject for it.

Using Daniel's library, our Async helper and interfaces for our web services, we can write beautiful web service-calling code in Silverlight:

public void GetFoos(IWebService1 webService1, IWebService2 webService2,
    IWebService3 webService3)
{
    Async.Execute(() =>
    {
        var data1 = webService1.GetFoo1();
        var data2 = webService2.GetFoo2();
        var data3 = webService3.GetFoo3();

        var processedData1 = Process(data1);
        var processedData2 = Process(data2);
        var processedData3 = Process(data3);

        ProcessedFoos = Merge(processedData1, processedData2, processedData3);
    });
}

You can imagine the tangle we would end up with if we had tried to code this using Silverlight’s default Event-Based Async Pattern.

Also, having our own interface for each web service lets us inject mocks when unit testing:

[Test]
public void should_process_and_merge_foos()
{
    // Arrange
    var presentationModel = new FooPresentationModel();
    var mockWebService1 = new Mock<IWebService1>();
    var mockWebService2 = new Mock<IWebService2>();
    var mockWebService3 = new Mock<IWebService3>();

    mockWebService1.Setup(x => x.GetFoo1()).Returns(new Foo());
    mockWebService2.Setup(x => x.GetFoo2()).Returns(new Foo());
    mockWebService3.Setup(x => x.GetFoo3()).Returns(new Foo());

    // Act
    presentationModel.GetFoos(mockWebService1.Object,
        mockWebService2.Object, mockWebService3.Object);

    // Assert
    Assert.AreEqual(3, presentationModel.ProcessedFoos.Count());
}

(Whoa – NUnit for Silverlight? Yes, let Jamie Cansdale show you how. I like Moq for mocking.)

The implementation of our web service interface uses Daniel’s library from CodeProject:

public class WebService1Impl : IWebService1
{
    public Foo GetFoo1()
    {
        var channel = ChannelManager.Instance.GetChannel<WebService1Contract>();
        return SynchronousChannelBroker.PerformAction<Foo>(channel.BeginGetFoo1, channel.EndGetFoo1);
    }
}

(WebService1Contract is the proxy class generated by Visual Studio or slsvcutil.exe).

Synchronous web service calls gives us code that is readable, testable and familiar. What's not to like?

In Silverlight, prefer synchronous web service calls over the Event-Based Async Pattern.

Hope this helps,

Andreas Hallberg
Consultant at Jayway

Tags: , ,

3 comments ↓

#1 Magnus Mårtensson on 06.11.10 at 9:19

That is just beautiful code man! Very good work!

#2 The Morning Brew - Chris Alcock » The Morning Brew #619 on 06.11.10 at 9:38

[...] Silverlight: Prefer synchronous web service calls – Andreas Hallberg looks at a way of calling web services in the standard synchronous way when working in Silverlight (although doing it on a different thread), looking at the advantages of working this way in terms of code simplicity and testability. [...]

#3 Andrew Lee on 06.11.10 at 12:14

Great work! Event based Async was always a pain when trying to aggregate the result of multiple webservice calls

Leave a Comment