Project Description

This library is intended to help developers leverage WCF without needing to add a service reference to services they control; it has been developed in C# and examples are packaged with the solution. This library is intended to work with Silverlight 4/5 and Full Framework (.NET 4.0 and up) projects.

Updates

  • 6/1/2013
  • 1/6/2012
    • Changed the model for finding the appropriate way of dispatching back to the UI thread
    • Added a download for the Silverlight 4 compatible libarary

How It Works

When you create a new WcfClient<T> (or call WcfClient<T>.CreateClientAsync()) a check is made to determine whether or not a proxy for the service contract T has been made yet. If it has not, a new contract is generated with corresponding APM signatures and a client (reasonably similar to the one you'd get by saying "Add Service Reference") is generated. A linkage is made internally between type T and this newly generated proxy definition so that for the rest of this execution of the program that proxy type will be used when referring to a service known by that contract and not have to generate a new one. Similarly, each synchronous method is linked up to its corresponding Begin/End method pair immediately after generation.

Methods calls on the service are made via the WcfClient<T>.Call(...) methods. The method on the service to call is selected via a LINQ expression like service => service.DoSomething(arg0, arg1) and the result of the call is passed into the specified Action<TResult, Exception> or Action<Exception> continuation method parameter (depending on whether the service method has a return type - TResult - or not). When Call executes it:
  1. Locates the Begin/End method pair that correspond to the method from the expression
  2. Evaluates each of the parameters given in the expression
  3. Prepares an object[] with enough elements to hold the arguments to the method plus the OnComplete callback and AsyncState
  4. Sets the OnComplete callback's slot in the array to be the End method from the pair (which will execute the continuation method - ideally on the UI thread)
  5. Invokes the Begin method with the object array as the parameters

Example Usage

Service Contract
// This contract must be defined in such a way that it is accessible to both the
// service's implementation and to the client.  In the examples, this is done by
// using a Portable Class Library though using "linked" files should work just
// as well.  Notice that the signatures for the Async Pattern Methods do not
// need to be specified.
[ServiceContract]
public interface IMyService
{
     [OperationContract]
     string DoSomething(string param0, string param1);
}

Service Implementation
// Include the following two attributes on your service if it will need to be called
// from a Silverlight application.  That aside, the implementation of the service
// does not have any special considerations for working with this library.
[SilverlightFaultBehavior]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class MyService : IMyService
{
     public string DoSomething(string param0, string param1)
     {
          return param0 + " " + param1;
     }  
}

Calling the Service
public class Program
{
     static void Main()
     {
          // Create a new client for the service contract IMyService using the default
          // binding for type IMyService from the configuration file for the app.
          // Overloaded constructors are available to use named configurations, etc.
          var client = new WcfClient<IMyService>();

          // Call the method "DoSomething" on the service with parameters "Hello" 
          // and "There" and invoke the method DoSomethingResultReceived when 
          // a response from the service has been returned
          client.Call(x => x.DoSomething("Hello", "There"), DoSomethingResultReceived);
     }

     // Notice that the first parameter in this method (used as the continuation for
     // the service call made above) takes two parameters:
     // The first (string) is the return type of the method from the service
     // The second (Exception) is used to notify the client of any exceptions 
     //      encountered while making the call to the service
     static void DoSomethingResultReceived(string message, Exception ex)
     {
          if(null == ex)
          {
               //The call to the server succeeded, process the result
               ...
          }
          else
          {
               //The call to the server failed, handle the error
               ...
          }
     }
}

More Information

  • All service methods are invoked as their Async pattern counterparts though the APM style signatures do not need to be defined in the service contract
  • The result of the service call is passed into the continuation method parameter in the Call method
  • In order to open the solution from source control the following Visual Studio tools are required:

Links

Last edited Jun 1, 2013 at 9:58 PM by mlorbetske, version 13