• Using WCF services in Prism Silverlight applications

    Published by on October 12th, 2011 11:26 am under Prism, Silverlight

    3 Comments

    There have been some discussions (e.g. this one) where people using Prism wonder how to include service references (for example, to WCF services) to Prism applications. It has been shown, for example in this blog post and this other one that this is possible with certain precautions.

    However, the auto generated proxy classes that are created when including WCF service references might not be easily integrated in a Prism application, which has testability requirements, and most likely uses a DI container.

    Here I will show a possible way to add a reference to a WCF service inside a Prism Silverlight application, exposing the service functionality as a shared service.

    image

    The big picture

    The sample application I created contains:

    • An infrastructure project (HelloWorld.Infrastructure) with a Customer class and a ICustomerServiceAgent interface,
    • A web project (HelloWorld.Silverlight.Web) that defines a WCF service using the Customer class (linked) as the data contract,
    • A Prism shell project (HelloWorld.Silverlight) containing the Shell with the main region and the application bootstrapper, and a link to the ServiceReferences.ClientConfig file (necessary for the service reference to work),
    • A ServicesModule that has a service reference to the WCF service defined in the Web project, and provides an implementation of ICustomerServiceAgent,
    • A HelloWorldModule that consumes the ICustomerServiceAgent and displays the data obtained from the service in a DataGrid.

    SNAGHTML658335

    The CustomerServiceAgent class, defined inside the ServicesModule, is exported in the container using the ICustomerServiceAgent interface as the contract type, thus becoming a shared service that can be consumed throughout the application.

    The implementation

    The CustomersService, as defined in the web project, exposes simply a GetCustomers method which returns a list of Customer entities. Customer entities have a FullName, a Company and an Address.

    The implementation provided for this service in the web project is a mock one, that simply returns a hardcoded list of customers, with a fixed name, a fixed company, and an address with random numbers.

    Now back to the client side of the application, the ICustomerServiceAgent interface provides a LoadCustomers method that accepts a callback (which has an ObservableCollection of Customers as the parameter):

    1 public interface ICustomerServiceAgent 2 { 3 void LoadCustomers(Action<ObservableCollection<Customer>> callback); 4 }

    And then, the implementation of this interface in the ServicesModule consumes the WCF service through the auto-generated service proxy (which is the result of the service reference), and exposes the LoadCustomers method as defined in the interface, abstracting away the details of how the asynchronous request to the service is made:

    1 [Export(typeof(ICustomerServiceAgent))] 2 public class CustomerServiceAgent : ICustomerServiceAgent 3 { 4 private readonly ICustomersService WCFServiceClient; 5 6 public CustomerServiceAgent() 7 { 8 this.WCFServiceClient = new CustomersServiceClient(); 9 } 10 11 public void LoadCustomers(Action<ObservableCollection<Customer>> callback) 12 { 13 this.WCFServiceClient.BeginGetCustomers( 14 (e) => Deployment.Current.Dispatcher.BeginInvoke( 15 () => callback(this.WCFServiceClient.EndGetCustomers(e))), 16 null); 17 } 18 } 19  

    You can find the solution in my SkyDrive account, under the name WCFServiceAgentSample. This code is provided “AS IS” with no warranties and confers no rights.

    As a final note, It’s worth mentioning that, to prepare this sample, I checked the following blog post:

    Even though I created a sample using a plain WCF service in Prism, the idea can be extrapolated to WCF RIA Services, using as well the abstraction strategies proposed in Dan Wahlin’s post.

    Tags: , ,

    • Sven

      Do you have also an example of this for WPF?

    • truyenle

      Great article, help me a lot. especially for the newbie in web service like me.

      I got a question. What if I need to use this web server to pass a string to the server?I mean how is the callback look like.
      public void LoadCustomers(Action<ObservableCollection> callback)
      {
      this.WCFServiceClient.BeginGetCustomers(
      (e) => Deployment.Current.Dispatcher.BeginInvoke(
      () => callback(this.WCFServiceClient.EndGetCustomers(e))),
      null);
      }

      I guess that I have to modify this but don’t know how to?

    • Fred Ward

      this.WCFServiceClient = new CustomersServiceClient());

      Showing an error – An instance of type ServiceModule.CustomersServiceClient can not be assigned to a variable of type ServicesModule.CustomersService.ICustomersService

      callback(this.WCFServiceClient.EndGetCustomers(e))),

      Arguments are not applicable to delegate System.Action<System.Collections.ObjectModel.ObservableCollection>