Beginner's Guide to Windows Communication Foundation

Description

 
Windows Communication Foundation (WCF) is Microsoft's implementation of set of industry standards defining service interactions. WCF unifies the previous generations of Microsoft's technologies, offering the interoperability of ASP.NET web services, the extensibility of remoting and the productivity and power of Enterprise Services. Those who previously built multiple code bases to deal with web services and .NET remoting will surely come to appreciate the power of standardization that WCF offers. This article starts by explaining the motivation for service-orientation, and then continues to discuss in depth how to develop service-oriented applications using WCF. You will see how to take advantage of some of the built-in features such as service hosting. While the article shows how to use these features, it sets the focus on the 'why' and the rationale behind particular design decisions, often shedding light on poorly-documented and understood aspects. You will learn not only WCF programming, but also relevant design guidelines, best practices, and pitfalls. The objective of the training is not to just make you a WCF expert, but also a better software engineer.
 
This article will assume no prior experience with WCF, and will walk you through some basic exercises and steps to show WCF's capabilities.
 

Introduction to Service-Orientation

 
Most of the time we hear people around us, speaking about Service Oriented Architecture(SOA). And each one of them will have their own definition for SOA. To begin with, we will start understanding what exactly SOA is. The Organization for the Advancement of Structured Information Standards, better known as OASIS (http://www.oasis-open.org), provides this official definition in its Reference Model for Service Oriented Architecture:
 
Service Oriented Architecture (SOA) is a paradigm for organizing and utilizing distributed capabilities that may be under the control of different ownership domains.
 
To elaborate, SOA relies on the ability to access chunks of business functionality, potentially owned by different applications, departments, companies, or industries.
 

Enterprise Application Development Approach

 
We generally follow any of the below listed approaches, for the development of Enterprise Applications:
  • Object Oriented Programming
  • Component Oriented Programming
  • Service Oriented Programming
There is a common goal behind all three of the above mentioned approaches i.e., Encapsulation and re-use. We gradually shifted from OOP to SOA, as developers progressed building more complex enterprise systems. Now, let us look at the in-depth details which made us to shift from OOP to SOA.
 
Object Oriented Programming
 
With object-oriented programming, classes encapsulate functionality and provide code-reuse. To share classes between distinct applications or binaries, however, you have to copy the code as shown in the figure below:
 
 
Figure 1. Duplicating types between components
 
Component Oriented Programming
 
Component-oriented programming introduces the concept of sharing binaries that encapsulate reusable classes. Initially, this was limited to the same machine until distribution was made possible with technologies like COM and DCOM, CORBA, and later Enterprise Java Beans (EJBs) and .NET Remoting. Although these technologies accomplish distribution in different ways the result is the same-binary components are activated over process and machine boundaries.
 
 
Figure 2. Shared component containing shared types
 
Component-oriented programming has many limitations, but the most obvious is tight coupling to a specific technology. How can a Java client call a COM component? How can a .NET assembly invoke an EJB? It all boils down to protocols and messaging formats.
 
Service Oriented Programming
 
Invoking a remote component of any kind requires serializing a message and passing it across applicable process or machine boundaries. Bridge technologies and adapters exist to transform messages from one technology into another, so that when the message arrives it can be understood and processed. The reverse happens as responses are fed back to the caller. This approach is cumbersome, however, sometimes introducing multiple transformations between clients and components- and sometimes not even possible. Instead of exposing components directly, components can be accessed through service boundaries to alleviate some of this pain.
 
 
Figure 3. Exposing functionality through a service boundary
 
service-orientation delivers a solution to the problems of distributed computing by introducing the concept of contracts, policies, and interoperability. In that respect, applications can communicate with one another's services, without concern over the technology each employs. Also, service-orientation is an approach to development that implies the encapsulation of business components, data access, and data storage such that access is controlled through a top-level entry point. The package is a service, accessible over whatever protocols are supported, even if it lacks interoperability.
 
SOA is all about building an enterprise system where, developers must be able to distribute chunks of functionality across process and machine boundaries to deal with performance bottlenecks, to introduce security boundaries, and to facilitate reuse.
 
A service can be developed using any existing technology. It could be a serviced component exposed using Enterprise Services, a .NET Remoting component, an ASMX web service, or a WCF service. Any of these technologies can be useful in exposing the business logic in such a way that the client can reach that functionality at remote locations in a distributed environment, without communicating directly with business components. Serviced components are reached using DCOM over TCP, .NET Remoting components via RPC over TCP, ASMX web services via SOAP over HTTP etc.,
 
You get into problem only when the service has to be exposed over multiple protocols. That is when, you need to depend on multiple programming models to support each protocol. We will see how to solve this problem later in this article.
 

Overview of Windows Communication Foundation

 
WCF simplifies development of connected applications through a new service-oriented programming model. WCF supports many styles of distributed application development by providing a layered architecture. At its base, the WCF channel architecture provides asynchronous, untyped message-passing primitives. Built on top of this base are protocol facilities for secure, reliable, transacted data exchange and broad choice of transport and encoding options. To understand the need of WCF, we will go through a problem scenario and discuss about the solutions with/without WCF.
 

Problem Scenario

 
The following example illustrates some of the problems that WCF addresses. A car rental company decides to create a new application for reserving cars. The management expects the application to be able to communicate with other software systems that are already running inside and outside their company.
 
Figure 4. Car Rental Company expected architecture
 
Solution without WCF
 
The development team that implements the rental car application would need to choose the right distributed technology from the multiple choices offered by the .NET Framework. Yet given the diverse requirements of this application, no single technology would fit the requirements. Instead, the application would probably use multiple existing .NET Framework technologies, such as the following:
  • ASP.NET Web services (ASMX). An option for communicating with the J2EE-based existing reservation application and with the partner applications across the Internet
  • .NET Framework remoting. An option for communication with the call center application, because both are built on the .NET Framework.
  • Enterprise Services. Used by the rental car reservation application for managing object lifetimes and defining distributed transactions.
  • WSE. Could be used along with ASMX to communicate with the J2EE-based reservation application and with the partner applications. Because it implements more recently defined Web services agreements, known collectively as the WS-* specifications, WSE allows for more flexible Web services security, as long as all applications involved support compatible versions of these new specifications.
  • Microsoft Message Queuing (MSMQ). Used to communicate with Windows-based partner applications that require guaranteed data delivery as well as decoupling of workloads and application lifetimes. The durable messaging that Message Queuing provides is typically the best solution for intermittently connected applications.
Built on .NET Framework, the rental car reservation application must use more than one of these communication technologies to meet its requirements. Although this is technically possible, the resulting application would be complex to implement and challenging to maintain.
 
Solution with WCF
 
With WCF, the solution is much easier to implement. As the figure shows, WCF can be used for all the situations previously described. Accordingly, the rental car reservation application can use this single technology for all of its application-to-application communication. The following shows how WCF addresses each of these requirements:
  • Because WCF can communicate using Web services, interoperability with other platforms that also support SOAP, such as the leading J2EE-based application servers, is straightforward.
  • You can also configure and extend WCF to communicate with Web services using messages not based on SOAP, for example, simple XML formats like RSS.
  • Performance is of paramount concern for most businesses. WCF is developed with the goal of being one of the fastest distributed application platform developed by Microsoft..
  • To allow optimal performance when both parties in a communication are built on WCF, the wire encoding used in this case is an optimized binary version of an XML Information Set. Messages still conform to the data structure of a SOAP message, but their encoding uses a binary representation of that data structure rather than the standard angle-brackets-and-text format of the XML 1.0 text encoding. Using this option makes sense for communicating with the call center client application, because it is also built on WCF, and performance is an important concern.
  • Managing object lifetimes, defining distributed transactions, and other aspects of Enterprise Services are now provided by WCF. They are available to any WCF-based application, which means that the rental car reservation application can use them with any of the other applications it communicates with.
  • Because it supports a large set of the WS-* specifications, WCF helps provide reliability, security, and transactions when communicating with any platform that also supports these specifications.
  • The WCF option for queued messaging, built on Message Queuing, allows applications to use persistent queuing without using another set of application programming interfaces.
The result of this unification is greater functionality and significantly reduced complexity.
 
Figure 5. Solution for Car Rental Company problem with WCF
 
WCF addresses a range of challenges for communicating applications. Three things stand out, however, as the most important aspects of WCF:
  • Unification of existing .NET Framework communication technologies.
  • Support for cross-vendor interoperability, including reliability, security, and transactions.
  • Explicit service orientation.
Now, you understood the need of Windows Communication Foundation to facilitate current and future requirements. Letz move a step ahead and try to understand more about WCF.
 

WCF Software Requirements

 
We'll now cover the software platform requirements for both developing and running .NET 3.0 applications. WCF is part of the .NET 3.0 Framework API that is fully integrated into the major release of Windows-Windows Vista. Microsoft is also making the .NET 3.0 Framework backward compatible for certain versions of Windows, specifically Windows XP Service Pack 2 and Windows 2003 Service Pack 1.
 
The following are the component requirements to run and develop .NET 3.0 and WCF-based applications:
  1. Windows 2003 Service Pack 1/ Windows XP Service Pack 2/ Windows Vista
  2. The .NET Framework 2.0 redistributable package (x86/x64/I64), which is part of Vista (this is an add-on for Windows 2003 and XP Service Pack 2)
  3. The .NET 3.0 Framework components, which are part of Vista (these are add-ons for Windows 2003 and XP Service Pack 2)
The development environment requires a few extra tools and, as a general recommendation, should be equipped with a bit more resources for the hardware-specifically RAM, CPU, and disk space:
  • Windows 2003 Service Pack 1/ Windows XP Service Pack 2/ or Windows Vista
  • The .NET Framework 2.0 redistributable package (x86/x64/I64), which is part of Vista
  • The .NET Framework 2.0 SDK (x86/x64/I64)
  • The Microsoft Windows SDK-formerly known as Platform SDK
  • The .NET Framework 3.0 runtime components (RTC), which are already included in Windows Vista
  • Recommended: IIS installation-not required with Visual Studio 2005 development web server
  • Recommended: Microsoft Visual Studio 2005 Express Edition (or "larger" version-Pro, Suite, and so on)
  • Recommended: The .NET Framework 3.0 Development Tools for Visual Studio
Note that the .NET Framework 3.0 Development Tools for Visual Studio 2005 provide template support for .NET 3.0 projects and project items. They are not required, but they make working with WCF and .NET 3.0-based solutions and components inside Visual Studio 2005 a little bit easier because they add all the references and template code for you. [Visual Studio 2005 Extensions for .NET 3.0 Framework]
 

WCF Architecture

 
The following graphic illustrates the major layers of the Windows Communication Foundation (WCF) architecture.
 
Figure 6. WCF Architecture
 
Contracts and Descriptions
 
Contracts define various aspects of the message system. The data contract describes every parameter that makes up every message that a service can create or consume. The message contract defines specific message parts using SOAP protocols, and allows finer-grained control over parts of the message, when interoperability demands such precision. The service contract specifies the actual method signatures of the service, and is distributed as an interface in one of the supported programming languages, such as Visual Basic or Visual C#.
 
Policies and bindings stipulate the conditions required to communicate with a service. For example, the binding must (at a minimum) specify the transport used (for example, HTTP or TCP), and an encoding. Policies include security requirements and other conditions that must be met to communicate with a service.
 
Service Runtime
 
The service runtime layer contains the behaviors that occur only during the actual operation of the service, that is, the runtime behaviors of the service. Throttling controls how many messages are processed, which can be varied if the demand for the service grows to a preset limit. An error behavior specifies what occurs when an internal error occurs on the service, for example, by controlling what information is communicated to the client. (Too much information can give a malicious user an advantage in mounting an attack.) Metadata behavior governs how and whether metadata is made available to the outside world. Instance behavior specifies how many instances of the service can be run (for example, a singleton specifies only one instance to process all messages). Transaction behavior enables the rollback of transacted operations if a failure occurs. Dispatch behavior is the control of how a message is processed by the WCF infrastructure.
 
Messaging
 
The messaging layer is composed of channels. A channel is a component that processes a message in some way, for example, by authenticating a message. A set of channels is also known as a channel stack. Channels operate on messages and message headers. This is different from the service runtime layer, which is primarily concerned about processing the contents of message bodies.
 
There are two types of channels: transport channels and protocol channels.
 
Transport channels read and write messages from the network (or some other communication point with the outside world). Some transports use an encoder to convert messages (which are represented as XML Infosets) to and from the byte stream representation used by the network. Examples of transports are HTTP, named pipes, TCP, and MSMQ. Examples of encodings are XML and optimized binary.
 
Protocol channels implement message processing protocols, often by reading or writing additional headers to the message. Examples of such protocols include WS-Security and WS-Reliability.
 
Hosting and Activation
 
In its final form, a service is a program. Like other programs, a service must be run in an executable. This is known as a self-hosted service.
 
Services can also be hosted, or run in an executable managed by an external agent, such as IIS or Windows Activation Service (WAS). WAS enables WCF applications to be activated automatically when deployed on a computer running WAS. Services can also be manually run as executables (.exe files). A service can also be run automatically as a Windows service. COM+ components can also be hosted as WCF services.
 

WCF Terminology

 
Services
 
WCF applications expose functionality through services. A service is a Common Language Runtime (CLR) type that encapsulates business functionality and exposes a set of methods that can be accessed by remote clients. In order for a regular CLR type to be considered a service it must implement a service contract.
 
A service contract is defined by applying the ServiceContractAttribute to a class or interface. When applied to a class, the class becomes a service type. When applied to an interface, any class that implements the interface becomes a service type. In either case, methods exposed by the class or interface must be decorated with the OperationContractAttribute to be considered part of the service contract. Methods with this attribute are considered service operations. A service type must be hosted before clients can invoke service operations.
 
Hosting
 
Service functionality is made available at runtime through a host process-any managed process will do the trick. Many hosting options are available for WCF services,including:
  • Self-hosting
    This includes console applications, Windows Forms or WPF applications, or Windows services.
  • Internet Information Services (IIS)
    Services can be hosted alongside other ASP.NET applications, for example.
  • Windows Activation Service (WAS)
    This is similar to IIS hosting but is only available to IIS 7.0.
Endpoints
 
When the ServiceHost opens a communication channel for a service, it must expose at least one endpoint for the service so that clients can invoke operations. In fact, endpoints are the key to invoking service functionality. An endpoint describes where services can be reached, how they can be reached, and what operations can be reached.
 
Thus, endpoints have three key parts:
  • Address
    Refers to the URI where messages can be sent to the service.
  • Binding
    Bindings indicate the protocols supported when messages are sent to a particular address.
  • Contract
    Each address supports a specific set of operations, as described by a service contract.
The ServiceHost is provided with a list of endpoints before the communication channel is opened. These endpoints each receive messages for their associated operations over the specified protocols.
 
Addresses
 
Each endpoint is associated with an address, identified by a URI. An address has a scheme, domain, port, and path in the following format: scheme://domain[:port]/[path].
The scheme indicates the transport protocol being used, such as TCP, named pipes, HTTP, or MSMQ. Respectively, the schemes for these protocols are net.tcp, net.pipe, http, and net.msmq. The domain refers to either a machine name or web domain. Sometimes localhost is used for communications on the same machine. The port can be specified to use a specific communication port other than the default for the protocol identified by the scheme. For example, HTTP defaults to port 80. Here are some examples of valid base addresses before specifying a path:
net.tcp://localhost:9000
net.pipe://mymachinename
http://localhost:8000
http://www.anydomain.com
net.msmq://localhost
A path is usually provided as part of the address to disambiguate service endpoints. The path does not usually include a filename for self-hosting, but with IIS a physical file is implicitly included in the address.
 
These are valid self-hosting addresses that include paths:
net.tcp://localhost:9000/ServiceA
net.pipe://mymachinename/ServiceB
http://localhost:8000/Services/ServiceA
http://www.mydomain.com/ServiceA
net.msmq://localhost/QueuedServices/ServiceA
When you add endpoints to a ServiceHost instance, you must specify a unique address for each endpoint. That means that you must vary at least one of the scheme, domain, port, or path specified.
 
Bindings
 
A binding describes the protocols supported by a particular endpoint, specifically, the following:
  • The transport protocol, which can be TCP, named pipes, HTTP, or MSMQ
  • The message encoding format, which determines whether messages are serialized as binary or XML, for example
  • Other messaging protocols related to security and reliability protocols, plus any other custom protocols that affect the contents of the serialized message
There are a number of predefined bindings (called standard bindings) provided by the service model. These standard bindings represent a set of typical protocols representative of common communication scenarios.
 
Metadata
 
Once the ServiceHost is configured for one or more endpoints, and communication channels are open, service operations can be invoked at each endpoint. This is according to the protocols supported by each endpoint. Clients invoke service operations at a particular endpoint. To do so, they need information about the endpoint, including the address, the binding, and the service contract. Information about service endpoints is part of the metadata for a particular service. Clients rely on this metadata to generate proxies to invoke the service.
 
Metadata can be accessed in two ways. The ServiceHost can expose a metadata exchange endpoint to access metadata at runtime, or it can be used to generate a WSDL document representing the endpoints and protocols supported by the
 
Proxies
 
Clients communicate with services using proxies. A proxy is a type that exposes operations representative of a service contract that hides the serialization details from the client application when invoking service operations. For WCF applications, proxies are based on the service contract, so if you have access to the service contract definition, you can create a proxy instance to invoke the service. Before the proxy instance can be used to call service operations, it must be provided with information about one of the endpoints exposed for that service contract-there is a one-to-one relationship between proxy and endpoint.
 
Tools also exist to generate proxies and endpoint configurations from metadata. In this chapter, you will learn how to create a proxy manually, without generating metadata, and how to use proxy generation tools. In either case, the client must open a communication channel with the service to invoke operations. This channel must be compatible with the channel exposed by the ServiceHost for communications to work.
 
Channels
 
Channels facilitate communication between clients and services in WCF. The ServiceHost creates a channel listener for each endpoint, which generates a communication channel. The proxy creates a channel factory, which generates a communication channel for the client. Both communication channels must be compatible for messages between them to be processed effectively. In fact, the communication channel is comprised of a layered channel stack-each channel in the stack is responsible for performing a particular activity while processing a message. The channel stack includes a transport channel, a message-encoding channel, and any number of message processing channels for security, reliability, and other features.
 
Behaviors
 
Behaviors also influence how messages are processed by the service model. While services and endpoints determine the core communication requirements and metadata shared with clients, a behavior modifies the way messages are processed as they flow through the channel stack. Behaviors are local to the client or service-thus, they are not included in metadata.
 
There are behaviors to control many service model features such as exposing metadata, authentication and authorization, transactions, message throttling, and more. Behaviors are enabled either in configuration or by applying behavior attributes to client proxies and services.
 

Building your first WCF Application

 
Building the Contract
 
Code time! Your first step is to build the contract. Contract is nothing but an interface in well known terms. Let's start with creating a simple helloWorld application. You'll create an interface that establishes the WCF contracts for any clients that consume the service.
 
So do the following:
  1. Open Visual Studio 2005 and create a new class library project called DemoInterfaces.
  2. In Solution Explorer, right-click on references and add a .NET reference to System.ServiceModel.
  3. Add new interface to the project named "ICustomer.cs"
  4. Copy and paste below specified interface into ICustomer.cs
    1. using System.ServiceModel;  
    2. namespace DemoInterfaces   
    3. {   
    4.     [ServiceContract]   
    5.     public interface ICustomer   
    6.     {   
    7.         [OperationContract]   
    8.         string SayHello(string name);   
    9.     }   
    10. } 
  5. Build the project, which will create DemoInterfaces.DLL.
System.ServiceModel is the primary DLL in the .NET 3.0 Framework for WCF. Make sure to add a .NET reference to System.ServiceModel any time you write code using the WCF object model.
 
The code for the public interface ICustomer contains two new keyword attributes: ServiceContract and OperationContract.
 
The ServiceContact attribute defines the operations that a service can perform, and the OperationContract attribute identifies the exact methods. The .NET CLR will translate these interfaces to SOAP types.
 
[ServiceContract] attribute can be applied either to the interface or to the class directly. [ServiceContract] attribute is just an indication for the WCF runtime that this CLR type can be hosted as a WCF service. Without this attribute a type cannot be hosted as a WCF service.

[OperationContract] attribute can be applied either to the method declarations in the interface or to definitions in the class directly[OperationContract] attribute is just an indication for the WCF runtime that this method can be exposed to the outside word as part of the service. Consider this attribute as similar to [WebMethod] attribute, without which a method cannot be exposed to the outside world.
 
You'll use this interface on both the server that hosts the WCF service as well as the client that uses it. The interface is your contract between the client and the server.
 
Building the Business Object
 
Now that you've established the contract (interface), the next step is to build the business object that implements the contract.
 
To create the business object, do the following:
  1. Create a new class library project called DemoCustomerBz.
  2. In Solution Explorer, right-click on references and add a .NET reference to System.ServiceModel.
  3. In Solution Explorer, right-click on references and add a .NET reference to the DemoInterfaces.DLL that you created when you built the interface project in the previous step.
  4. Add a new class to the project named "Customer.cs"
  5. Copy and paste below specified code into "Customer.cs"
    1. using DemoInterfaces;   
    2. namespace DemoCustomerBz   
    3. {   
    4.     public class Customer:ICustomer   
    5.     {   
    6.         #region ICustomer Members   
    7.         public string SayHello(string name)   
    8.         {   
    9.             return "Hello " + name + "!...";   
    10.         }   
    11.         #endregion   
    12.     }   
    13. } 
  6. Build the project, which will create DemoCustomerBz.DLL
Building the Service Host Application
 
In the last step, we have created the customer business object. As the type CustomerBz is implementing the interface, which is marked with [ServiceContract] attribute, it can be hosted as a service.
 
Remember, all the types which are marked with [ServiceContract] are known as services. These services can not be exposed on its own. We need a Host process to host these services.
 
To create the host application, do the following:
  1. Create a new console application project called DemoCustomerHost.
  2. In Solution Explorer, right-click on references and add a .NET reference to System.ServiceModel.
  3. In Solution Explorer, right-click on references and add a .NET reference to the previously created libraries: DemoInterfaces.DLL and DemoCustomerBz.Dll.
  4. Double click on "program.cs" to open the file
  5. Copy and paste below specified code into "program.cs"
    1. using System;   
    2. using System.ServiceModel;   
    3. using DemoInterfaces;   
    4. using DemoCustomerBz;   
    5. namespace DemoCustomerHost   
    6. {   
    7.     class Program   
    8.     {   
    9.         static void Main(string[] args)   
    10.         {   
    11.             using (ServiceHost host = new ServiceHost(   
    12.                 typeof(Customer),   
    13.                 new Uri("http://localhost:8000/Customer")))   
    14.                 {   
    15.                 host.AddServiceEndpoint(   
    16.                     typeof(ICustomer), // Contract   
    17.                     new BasicHttpBinding(), // Binding   
    18.                     "CustomerService"); // Address   
    19.                 host.Open();   
    20.                 Console.WriteLine ("Service is up and running.");   
    21.                 Console.WriteLine("Press <Enter> to stop service...");   
    22.                 Console.ReadLine(); host.Close();   
    23.             }   
    24.         }   
    25.     }   
    26. } 
  6. Build the project, which will create DemoCustomerHost.Exe
The above code initializes a ServiceHost instance specifying the service type and a base address where relative service end points can be located. It also adds a single relative endpoint for the service. In this case, a base address is provided for HTTP protocol, and the relative endpoint uses one of the standard bindings, BasicHttpBinding, based on HTTP protocol.
 
Building the Client Application
 
Now, we are ready with the service and serviceHost applications. It is time to consume the service. Create a client application consume the service.
 
To create a client application, do the following:
  1. Create a new console application project called DemoClient.
  2. In Solution Explorer, right-click on references and add a .NET reference to System.ServiceModel.
  3. Client and Service need a contract to establish communication. To add the contract, in Solution Explorer, right-click on references and add a .NET reference to the previously created library: DemoInterfaces.DLL

    Client and Service need to share only Contract, Not Code. So, we need not to add reference to DemoCustomerBz.dl.

  4. Double click on "program.cs" to open the file
  5. Copy and paste below specified code into "program.cs"
    1. using System;  
    2. using DemoInterfaces;  
    3. using System.ServiceModel;  
    4. namespace DemoClient   
    5. {   
    6.     class Program   
    7.     {   
    8.         static void Main(string[] args)   
    9.         {   
    10.             ICustomer proxy = ChannelFactory<ICustomer>.  
    11.                 CreateChannel(  
    12.                 new BasicHttpBinding(),   
    13.                 new EndpointAddress("http://localhost:8000/Customer/CustomerService"));   
    14.             string result = proxy.SayHello("Test Client");   
    15.             Console.WriteLine("Server says : " + result);   
    16.             Console.WriteLine("Press <Enter> to stop client...");   
    17.             Console.ReadLine();   
    18.         }   
    19.     }   
    20. } 
  6. Compile the solution and run the host project first, followed by the client project.
  7. The client console output will be displayed as:



    The above code uses ChannelFactory to creat a new channel to invoke the service. This strongly typed channel reference acts as a proxy. The code also initializes an EndpointAddress with the correct address and binding expected by the service endpoint.
Building the Service Host Application using app.config
 
Previously, we created service host application which uses code to initialize host and endpoints for the service. The same can be achieved by adding configuration file rather than writing code. We will use the already created ServiceHost application DemoCustomerHost for this session.
  1. Open the already created project DemoCustomerHost.
  2. Double click on "program.cs" to open the file
  3. Copy and paste below specified code into "program.cs:
    1. using System;   
    2. using System.ServiceModel;   
    3. using DemoInterfaces;   
    4. using DemoCustomerBz;   
    5. namespace DemoCustomerHost   
    6. {   
    7.     class Program   
    8.     {   
    9.         static void Main(string[] args)   
    10.         {   
    11.             using (ServiceHost host = new ServiceHost(typeof(Customer)))   
    12.             {   
    13.                 // URI and endpoint information will be fetched from app.config   
    14.                 host.Open();   
    15.                 Console.WriteLine("Service is up and running.");   
    16.                 Console.WriteLine("Press <Enter> to stop service...");   
    17.                 Console.ReadLine();   
    18.                 host.Close();   
    19.             }   
    20.         }   
    21.     }   
    22. }
    The above code initializes a ServiceHost instance specifying the service type and no endpoint information have been specified in the code. When the required information is not available in the code, WCF runtime looks for the information in the application configuration file and adds endpoint information on the fly, to the service.
  4. Add new file to the application named "app.config"
  5. Copy and past below specified text into "app.config"
    1. <?xml version="1.0" encoding="utf-8" ?>  
    2. <configuration>  
    3.   <system.serviceModel>  
    4.     <services>  
    5.       <service name="DemoCustomerBz.Customer">  
    6.         <endpoint address="CustomerService" binding="basicHttpBinding" bindingConfiguration="" name="basicHttp" contract="DemoInterfaces.ICustomer" />  
    7.         <host>  
    8.           <baseAddresses>  
    9.             <add baseAddress="http://localhost:8000/Customer" />  
    10.           </baseAddresses>  
    11.         </host>  
    12.       </service>  
    13.     </services>  
    14.   </system.serviceModel>  
    15. </configuration>
    In the above config file, we are adding configuration entry for one endpoint which is accessed over basicHttpBinding at http://localhost:8000/Customer/CustomerService. We can add any number of end points to the service by adding multiple endpoint tags to the app.config.
  6. Build the project, which will create DemoCustomerHost.Exe

ProxyGeneration

 
In the previous demo, we have created service and client applications using WCF framework. In the current session, we will try to generate proxy on the fly and consume from the client application.
 
Building the Service Host Application to support Metadata Exchange
 
Previously in the client application, we have added reference to DemoInterfaces.dll. Because, we need to share contract information between client and service applications. The same can also be achieved without adding a reference to DemoInterfaces.dll.
 
To be able to communicate with service, without adding reference to DemoInterfaces.dll , client application should have knowledge of services and its methods, endpoint information exposed by the service host application. This information is known as Metadata. To exchange metadata, service host has to expose new endpoint with binding "mexHttpBinding". We will use previously created projects DemoCustomerHost and DemoClient for this session.
  1. Open the project DemoCustomerHost which uses app.config file
  2. Double click on the file "app.config" to open
  3. Copy and paste below specified text into "app.config"
    1. <?xml version="1.0" encoding="utf-8" ?>  
    2. <configuration>  
    3.   <system.serviceModel>  
    4.     <behaviors>  
    5.       <serviceBehaviors>  
    6.         <behavior name="metadataBehavior">  
    7.           <serviceMetadata httpGetEnabled="true" />  
    8.         </behavior>  
    9.       </serviceBehaviors>  
    10.     </behaviors>  
    11.     <services>  
    12.         <service behaviorConfiguration="metadataBehavior" name="DemoCustomerBz.Customer">  
    13.         <endpoint address="CustomerService" binding="basicHttpBinding" bindingConfiguration="" name="basicHttp" contract="DemoInterfaces.ICustomer" />  
    14.         <endpoint binding="mexHttpBinding" bindingConfiguration="" name="metadataExchange" contract="IMetadataExchange" />  
    15.         <host>  
    16.           <baseAddresses>  
    17.             <add baseAddress="http://localhost:8000/Customer" />  
    18.           </baseAddresses>  
    19.         </host>  
    20.       </service>  
    21.     </services>  
    22.   </system.serviceModel>  
    23. </configuration>
    In the above config file, we have added new endpoint to expose metadata for the clients. To expose metadata, we must enable httpGet, this is been done using serviceBehaviors configuration entry.
  4. Build the project, which will create DemoCustomerHost.Exe
Building Client using auto-generated proxy
 
To create a client application, do the following:
  1. Create a new console application project called DemoClient.
  2. In Solution Explorer, right-click on references and add a .NET reference to System.ServiceModel.
  3. Make sure that the host application created in the previous section is running, to generate proxy


     
  4. Right click on the project and select "Add service reference…"


     
  5. Provide URI for the service , specify namespace as "CustomerProxy and click on "Add" button


     
  6. Two files app.config and CustomerProxy will be generated and added automatically to the project.


     
  7. Auto generated app.config in the client app, looks as given below:
    1. <?xml version="1.0" encoding="utf-8" ?>  
    2. <configuration>  
    3.   <system.serviceModel>  
    4.     <bindings>  
    5.       <basicHttpBinding>  
    6.         <binding name="basicHttp" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true">  
    7.           <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />  
    8.           <security mode="None">  
    9.             <transport clientCredentialType="None" proxyCredentialType="None" realm="" />  
    10.             <message clientCredentialType="UserName" algorithmSuite="Default" />  
    11.           </security>  
    12.         </binding>  
    13.       </basicHttpBinding>  
    14.     </bindings>  
    15.     <client>  
    16.       <endpoint address="http://localhost:8000/Customer/CustomerService"  
    17. binding="basicHttpBinding" bindingConfiguration="basicHttp" contract="CustomerProxy.ICustomer" name="basicHttp" />  
    18.     </client>  
    19.   </system.serviceModel>  
    20. </configuration>  
  8. Double click on "program.cs" to open the file
  9. Copy and paste below specified code into Main() method of "program.cs"
    1. using System;   
    2. using DemoInterfaces;   
    3. using System.ServiceModel;   
    4. namespace DemoClient   
    5. {   
    6.     class Program   
    7.     {   
    8.         static void Main(string[] args)   
    9.         {   
    10.             CustomerProxy.CustomerClient proxy = new DemoClient.CustomerProxy.CustomerClient();   
    11.             //Binding and Endpoint information is retrieved from   
    12.             //App.config   
    13.             string result = proxy.SayHello("Test Client");   
    14.             Console.WriteLine("Server says : " + result);   
    15.             Console.WriteLine("Press <Enter> to stop client...");   
    16.             Console.ReadLine();   
    17.         }   
    18.     }   
    19. }
  10. Compile the solution and run the host project first, followed by the client project.
  11. The client console output will be displayed as:

Conclusion

 
WCF is an SDK for building service-oriented applications on Windows. It enables you to use classic CLR programming constructs, such as classes and interfaces, to deploy and consume services. The programming model is declarative and is largely attribute-driven. WCF interception-based architecture offers built-in facilities for managing many run-time aspects of services, and moving forward, it is the most productive way of building distributed applications on Windows.


Similar Articles