Distributed Application Communication Using WCF

Introduction

Windows Communication Foundation (WCF) is a subset of the .NET Framework that is designed to take interoperability in distributed application environments to the next level. With the emergence and acceptance of Web services and their accompanying protocols and standards, development of distributed applications has become a developer norm. WCF simplifies that development by introducing a service- oriented programming model that at its base provides asynchronous and untyped message-passing. Extending from the base are options and protocols designed to give the developer choice in transport and encoding methods among many other configurations.

Those familiar with .NET Remoting, .NET Web services and Enterprises Services will recognize and have a familiar development experience in WCF. In addition to the old tricks, WCF enables serialization capabilities that allow loose coupling and versioning of distributed application across various platforms. This allows development of each application in the environment to be performed more independently and with fewer maintenance issues. Integration with existing .NET Framework technologies such as COM+, Web Services Enhancements (WSE), Message Queuing and others is also provided within WCF.

Windows Communication Foundation comes with its own set of terms and expressions. Before beginning it is important to understand the following:


terms and expressions
Click here for larger image

The following link has additional WCF terms and definitions: http://msdn.microsoft.com/en- us/library/ms731079.aspx

Whether you are developing a Windows Communication Foundation application to communicate across different platforms, across the Internet, or just on the same server, there are several tasks required to build a WCF application. They are listed in order below:

  • Define the service contract
  • Implement the contract
  • Configure the service
  • Host the service
  • Consume the service via a client

The following walkthrough uses a console application to host the service and a WPF client application to consume the service. The WPF client application will retrieve a product list from the service, display it to the user and allow the user to delete individual products. To get started, create a new console application in Visual Studio using the Console Application template and name it WCFProductService.

This walkthrough will use a class called Product. Data will be created at runtime for purposes of the example but a more likely scenario is that you would communicate with a database to retrieve the data.

  using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Text;
  
  namespace WCFProductService
  {
      public class Product
      {
          public Product()
          { }
  
          public int ProductID { get; set; }
          public string ProductName { get; set; }
          public string ProductDesc { get; set; }
          public int Inventory { get; set; }
  
          public List<Product> GenerateProductList()
          {
              List<Product> returnList = new List<Product>();
  
              returnList.Add(new Product() { ProductID = 1, ProductName = "Ball", ProductDesc = "White, Round", Inventory = 10 });
              returnList.Add(new Product() { ProductID = 2, ProductName = "Bat", ProductDesc = "Wood", Inventory = 7 });
              returnList.Add(new Product() { ProductID = 3, ProductName = "Glove", ProductDesc = "Brown, Leather", Inventory = 3 });
              returnList.Add(new Product() { ProductID = 4, ProductName = "Helmet", ProductDesc = "Head Protection", Inventory = 12 });
              returnList.Add(new Product() { ProductID = 5, ProductName = "Pads", ProductDesc = "Body Protection", Inventory = 12 });
              returnList.Add(new Product() { ProductID = 6, ProductName = "Jersey", ProductDesc = "Team Spirit", Inventory = 2 });
              returnList.Add(new Product() { ProductID = 7, ProductName = "Foam Finger", ProductDesc = "Awesome", Inventory = 23 });
              returnList.Add(new Product() { ProductID = 8, ProductName = "Tape", ProductDesc = "Injury prevention", Inventory = 102 });
              returnList.Add(new Product() { ProductID = 9, ProductName = "Club", ProductDesc = "9 Iron", Inventory = 11 });
              returnList.Add(new Product() { ProductID = 10, ProductName = "Bag", ProductDesc = "Holds Clubs", Inventory = 6 });
              
              return returnList;
          }
      }
  }

Product.cs

Defining the Service Contract

To create the service contract you will first have to add a reference to System.ServiceModel.dll using the Solution Explorer. Once the reference is added to the project you will need to add the System.ServiceModel namespace to the project by adding the following using statement.

using System.ServiceModel;

Program.cs

Next define a new interface called IProductManager and apply the ServiceContract attribute to the interface. For this example specify the Namespace value of the attribute to "http://CompanyName.ProductManager". It is best practice to specify the namespace as it prevents the default namespace value being added to the contract name. This interface will be used later when implementing the service contract.

In the IProductManager interface you will then declare a method for each operation you wish to expose via the contract. Add a method to retrieve the product list and one to delete a product. Add the OperationContract attribute to each method you want to expose. When finished your interface should look similar to the following.

  // ...
  
     [ServiceContract(Namespace="http://CompanyName.WCFProductService")]
     public interface IProductManager
     {
         [OperationContract]
         List GetAllProducts();
         [OperationContract]
         void DeleteProduct(int n1);
     }
  
  // ...

Program.cs

Implementing the Contract

After creating the contract via the interface above you will then need to implement the interface. For this create a class called ProductManagerService that implements the IProductManager interface. Then implement each method that was defined in the interface within the ProductManagerService class. Your code should look similar to the following when finished.

  // ...
  
     public class ProductManagerService : IProductManager
     {
         public List<Product> GetAllProducts()
         {
             if (MasterProductList == null)
                 MasterProductList = new List<Product>();
             if (MasterProductList.Count == 0)
                 MasterProductList = Product.GenerateProductList();
  
             return MasterProductList;
         }
  
         public void DeleteProduct(int n1)
         {
             if (MasterProductList == null)
             {
                 // throw and handle exception
             }
  
             var productToDelete = (from p in MasterProductList
                                   where p.ProductID == n1
                                   select p).FirstOrDefault();
  
             MasterProductList.Remove(productToDelete);
          }
      }
  // ...

Program.cs

Distributed Application Communication Using WCF

Configuring the Service

After the service contract has been implemented you are now ready to configure the service. Configuring the service involves determining and then defining how the service will be exposed, the location where it will be found, the type of security and message encoding used to send and receive messages. Windows Communication Foundation provides an abundance of options when performing configuration.

There are two basic ways to set the configuration for the service. The first option is to use inline code which the walkthrough uses for configuration. The second option uses configuration files and takes full advantage of the .NET Framework's configuration technology. When the WCF service is hosted in IIS for example the configuration would be part of the Web.config file.

For those looking to gain efficiency through reuse, WCF includes common configurations in the form of bindings that allow you to quickly set up the more basic features. Bindings can be used either inline or through XML elements in configuration files. In the walkthrough, WCFProductService uses the BasicHttpBinding binding in code to configure the service. The BasicHttpBinding does not provide security by default so therefore should only be used in secured network environments or with added security. A full list of WCF provided bindings and details to make a determination on which binding would work best for your situation can be found at http://msdn.microsoft.com/en- us/library/ms730879.aspx.

Within the Main method add a BasicHttpBinding object with the following properties.

  BasicHttpBinding binding = new BasicHttpBinding();
  binding.MessageEncoding = WSMessageEncoding.Text;
  binding.Security.Mode = BasicHttpSecurityMode.None; // default

Program.cs

There are many additional properties on the object that configure various different aspects of the service. Take some time to get familiar with the options as not all need to be configured but are useful to know when determining the best configuration for your service.

The next configuration step is for the endpoints. Endpoints are where WCF services are 'found' and where you go to gather information about the WCF service. The contract, configuration information and the address come together to comprise an endpoint. The contract and configuration has already been coded leaving the address, or endpoint location, to be implemented.

In the Main method create a new Uri object for the service's base address.

  Uri address = new Uri("http://localhost:8000/WCFProductService");

Program.cs

The last configuration required is to make the service discoverable through metadata. In the System.ServiceModel.Description namespace there is a class called ServiceMetadataBehavior that allows you to configure your WCF service to publish metadata about itself when requested. For those familiar with ASP.NET Web services this would be similar to discovery and generating the WSDL and adding a Web Reference to your project. Instead now you are making a service discoverable so a Web Service proxy can be created on your client as you will see later in this article.

To enable metadata discovery first add a using reference to System.ServiceModel.Description. Next create a new ServiceMetadataBehavior object in the Main method and set its HttpGetEnabled property to true. In the next step you will add the behavior to the ServiceHost object.

  using System.ServiceModel.Description;
  
  // ...
  
  ServiceMetadataBehavior smdb = new ServiceMetadataBehavior();
  smdb.HttpGetEnabled = true;

Program.cs

Note that by default metadata publishing is disabled due to security concerns with overexposing your service's surface to attack. Alternatives exist that do not require you to publish the service's metadata. Using the ServiceModel Metadata Utility Tool (discussed later) you are still able to generate metadata and client code directly from your service assemblies.

Hosting the Service

Now that the service has been defined, implemented and configured it is time to create the service host object to host the service and expose the service via an endpoint. The first step is to create a new ServiceHost object to host the WCF service. Use the base address Uri object created in the previous step and for the implementation of the service contract use ProductManagerService.

Next add a service endpoint to the ServiceHost object. For parameters pass in the interface that is to be exposed (IProductManager), the previously created binding object and the endpoint's address. Note that the address used here is relative to the base address used by the ServiceHost object. Then, before starting the service, add the ServiceMetadataBehavior object created in the previous step to the ServiceHost object's Description.Behaviors collection.

The Open() method of the ServiceHost object tells the service to start waiting for incoming messages and the Close() method stops the service. When finished your Main method in Program.cs should look similar to the following.

 // ...
          
  static void Main(string[] args)
  {
      BasicHttpBinding binding = new BasicHttpBinding();
      binding.MessageEncoding = WSMessageEncoding.Text;
      binding.Security.Mode = BasicHttpSecurityMode.None; // default
          
      Uri address = new Uri("http://localhost:8000/WCFProductService");
          
      ServiceHost productServiceHost = new 
        ServiceHost(typeof(ProductManagerService), address);
          
      productServiceHost.AddServiceEndpoint(typeof(IProductManager),
                  binding, "ProductManager");
          
      ServiceMetadataBehavior smdb = new ServiceMetadataBehavior();
      smdb.HttpGetEnabled = true;
          
      try
      {
        productServiceHost.Description.Behaviors.Add(smdb);                                   
                          
      productServiceHost.Open();
      Console.WriteLine("ProductManager Service is open!");
             Console.ReadLine();
          
             productServiceHost.Close();
      }
      catch (CommunicationException ce)
      {
      // handle/log exception, clean up ServiceHost...
             productServiceHost.Abort();
      }
  }
          
// ...
        

Program.cs

Before moving on, take a minute to familiarize yourself with all the different options available in creating the ServiceHost object and adding the endpoint. One of the great benefits of Windows Communication Foundation is how many options you have and how configurable it is. At the same time it can also be a source of overwhelming confusion if you have not taken the time to understand all of what is available.

To test that the service is working run the console application from Visual Studio (for Vista and Windows 7 users make sure you are running VS as an administrator) and open IE to the service's debug page located at http:// localhost:8000/WCFProductService.

Note: If you are running Windows 7 you may need to run the following command from an administrator command prompt to view the page in IE.

netsh http add urlacl url=http://+:8000/WCFProductService user=[username]

Administrative Command Prompt command

Distributed Application Communication Using WCF

Building a WCF client

The final major step in this walkthrough is to create a client to consume the Windows Communication Foundation service that has just been created. The walkthrough will create the client using Windows Presentation Foundation (WPF but it is important to note that the client could be an ASP.NET Web Application, Java application or even another WCF service. The type of client is less important due to WCF's service oriented architecture that abstracts away the communication nightmare that once existed when integrating between multiple systems and platforms.

Open another instance of Visual Studio and create a new WPF project named WCFProductClient. If you are unfamiliar with WPF and feel more comfortable with Windows Forms or Console applications, those are both acceptable alternatives. On the main window create a ListBox control to display the product list data and add a button to delete the selected product from the list. Then create the event handlers for the Window loaded event and the button click event.

Now you will need to generate the proxy that will access the WCF service. There are 2 primary ways this can be accomplished and both yield the same results. The first is to use the Add Service Reference wizard within Visual Studio and the second is to use the ServiceModel Metadata Utility Tool (Svcutil.exe) provided by WCF. If you have the luxury of building a .NET based client and the WCF service publishes metadata as shown in the example above then using the Visual Studio wizard is the quickest and easiest method to generate the proxy. Other cases where the WCF service does not publish metadata then the ServiceModel Metadata Utility Tool will be used to generate the proxy.

The following two examples will walkthrough both methods of generating the proxy. Before using either method make sure to have the WCF service running.

Using the Visual Studio wizard, start by right-clicking on the References folder in the Solution Explorer and selecting the Add Service Reference option. Enter the WCF service's base address and click Go. The wizard will discover the service, exposed endpoints and the operations that those endpoints allow.


Visual Studio Add Service Reference Wizard
Click here for larger image

Figure 1.0 - Visual Studio Add Service Reference Wizard

Enter the Namespace you want to use for the proxy and select OK. Visual Studio will then generate the proxy and add all necessary references in the client project. When finished the client project will be setup to start using the WCF service without further configuration.

Using the ServiceModel Metadata Utility Tool, start by opening a Windows SDK console and navigate to the directory where you want to place the generated proxy code. Using the appropriate switches create the proxy with the following command. Once generated use Visual Studio to add the files to the client project by right-clicking on the solution and selecting Add, Existing Item.

  Svcutil.exe /language:cs /out:ProductManagerService.cs /config:app.config http://localhost:8000/WCFProductService

ServiceModel Metadata Utility Tool command

Regardless of the method used to generate the proxy, once generated it is very easy to configure and consume the WCF service. Using the two events, Windows Loaded and the Button Click, add the following WCF client code.

  private void Window_Loaded(object sender, RoutedEventArgs e)
  {
         ServiceReferenceProductManager.ProductManagerClient pmc = new WCFProductClient.ServiceReferenceProductManager.ProductManagerClient();
             
         lstProducts.ItemsSource = pmc.GetAllProducts();
  
         pmc.Close();
  }
  
  private void btnDeleteProduct_Click(object sender, RoutedEventArgs e)
  {
         ServiceReferenceProductManager.Product selectedProduct                = (ServiceReferenceProductManager.Product)lstProducts.SelectedItem;
  
         ServiceReferenceProductManager.ProductManagerClient pmc = new WCFProductClient.ServiceReferenceProductManager.ProductManagerClient();
         pmc.DeleteProduct(selectedProduct.ProductID);
  
         lstProducts.ItemsSource = pmc.GetAllProducts();
  
         pmc.Close();
  }

Window1.xaml.cs

This code populates the ListBox with the product list pulled from the WCF service and allows the user to delete the selected product.

Conclusion

You have just walked through creating a Windows Communication Foundation service by defining a service contract, implementing the contract, configuring and hosting the service then finally consuming the service via a WCF client.

About the Author

Matt Goebel is the Founder and President of AP Innovation, Inc. in Indianapolis, Indiana. He can be reached at 859-802-7591 or matt .goebel@apinnovation.com.



About the Author

Matt Goebel

Matt Goebel is the Founder and President of AP Innovation, Inc. in Indianapolis, Indiana. He can be reached at 859-802-7591 or matt.goebel@apinnovation.com.

Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: December 11, 2014 @ 1:00 p.m. ET / 10:00 a.m. PT Market pressures to move more quickly and develop innovative applications are forcing organizations to rethink how they develop and release applications. The combination of public clouds and physical back-end infrastructures are a means to get applications out faster. However, these hybrid solutions complicate DevOps adoption, with application delivery pipelines that span across complex hybrid cloud and non-cloud environments. Check out this …

  • CentreCorp is a fully integrated and diversified property management and real estate service company, specializing in the "shopping center" segment, and is one of the premier retail service providers in North America. Company executives travel a great deal, carrying a number of traveling laptops with critical current business data, and no easy way to back up to the network outside the office. Read this case study to learn how CentreCorp implemented a suite of business continuity services that included …

Most Popular Programming Stories

More for Developers

RSS Feeds