WCF(WINDOWS COMMUNICATION FOUNDATION)
Introduction to WCF:
Windows Communication Foundation (Code named Indigo) is a programming platform and runtime system for building, configuring and deploying network-distributed services. It is the latest service oriented technology; Interoperability is the fundamental characteristics of WCF. It is unified programming model provided in .Net Framework 3.0. WCF is a combined features of Web Service, Remoting, MSMQ and COM+. WCF provides a common platform for all .NET communication.
Advantage:
1. WCF is interoperable with other services when compared to .Net Remoting,where the client and service have to be .Net.
2. WCF services provide better reliability and security in compared to ASMX web services.
3. In WCF, there is no need to make much change in code for implementing the security model and changing the binding. Small changes in the configuration will make your requirements.
4. WCF has integrated logging mechanism, changing the configuration file settings will provide this functionality. In other technology developer has to write the code.
WCF Architecture
The following figure illustrates the major components of WCF.
[Wcf Architechture]
Figure 1: WCF Architecture
Contracts
Contracts layer are next to that of Application layer. Developer will directly use this contract to develop the service. We are also going to do the same now. Let us see briefly what these contracts will do for us and we will also know that WCF is working on message system.
Service contracts
- Describe about the operation that service can provide. Example, Service provided to know the temperature of the city based on the zip code, this service we call as Service contract. It will be created using Service and Operational Contract attribute.
Data contract
- It describes the custom data type which is exposed to the client. This defines the data types, are passed to and from service. Data types like int, string are identified by the client because it is already mention in XML schema definition language document, but custom created class or datatype cannot be identified by the client e.g. Employee data type. By using DataContract we can make client aware that we are using Employee data type for returning or passing parameter to the method.
Message Contract
- Default SOAP message format is provided by the WCF runtime for communication between Client and service. If it is not meeting your requirements then we can create our own message format. This can be achieved by using Message Contract attribute.
Policies and Binding
- Specify conditions required to communicate with a service e.g security requirement to communicate with service, protocol and encoding used for binding.
Service Runtime
- It contains the behaviors that occur during runtime of service.
* Throttling Behavior- Controls how many messages are processed.
* Error Behavior - Specifies what occurs, when internal error occurs on the service.
* Metadata Behavior - Tells how and whether metadata is available to outside world.
* Instance Behavior - Specifies how many instance of the service has to be created while running.
* Transaction Behavior - Enables the rollback of transacted operations if a failure occurs.
* Dispatch Behavior - Controls how a message is processed by the WCF Infrastructure.
Messaging
- 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 are the core abstraction for sending message to and receiving message from an Endpoint. Broadly we can categories channels as
* Transport Channels
Handles sending and receiving message from network. Protocols like HTTP, TCP, name pipes and MSMQ.
* Protocol Channels
Implements SOAP based protocol by processing and possibly modifying message. E.g. WS-Security and WS-Reliability.
Activation and Hosting
- Services can be hosted or executed, so that it will be available to everyone accessing from the client. WCF service can be hosted by following mechanism
* IIS
Internet information Service provides number of advantages if a Service uses Http as protocol. It does not require Host code to activate the service, it automatically activates service code.
* Windows Activation Service
(WAS) is the new process activation mechanism that ships with IIS 7.0. In addition to HTTP based communication, WCF can also use WAS to provide message-based activation over other protocols, such as TCP and named pipes.
* Self-Hosting
WCF service can be self hosted as console application, Win Forms or WPF application with graphical UI.
* Windows Service
WCF can also be hosted as a Windows Service, so that it is under control of the Service Control Manager (SCM).
IIS 5/6 Hosting
The main advantage of hosting service in IIS is that, it will automatically launch the host process when it gets the first client request. It uses the features of IIS such as process recycling, idle shutdown, process health monitoring and message based activation. The main disadvantage of using IIS is that, it will support only HTTP protocol.
Let as do some hands on, to create service and host in IIS
Step 1:Start the Visual Studio 2008 and click File->New->Web Site. Select the 'WCF Service' and Location as http. This will directly host the service in IIS and click OK.
Step 2: I have created sample HelloWorld service, which will accept name as input and return with 'Hello' and name. Interface and implementation of the Service is shown below.
IMyService.cs
[ServiceContract]
public interface IMyService
{
[OperationContract]
string HelloWorld(string name);
}
MyService.cs
public class MyService : IMyService
{
//#region IMyService Members
public string HelloWorld(string name)
{
return "Hello " + name;
}
// #endregion
}
Step 3: Service file (.svc) contains name of the service and code behind file name. This file is used to know about the service.
MyService.svc
<%@ ServiceHost Language="C#" Debug="true"
Service="MyService" CodeBehind="~/App_Code/MyService.cs" %>
Step 4: Server side configurations are mentioned in the config file. Here I have mention only one end point which is configured to 'wsHttpBinding', we can also have multiple end point with differnet binding. Since we are going to hosted in IIS. We have to use only http binding. We will come to know more on endpoints and its configuration in later tutorial. Web.Config
<endpoint address="http://localhost/IISHostedService/MyService.svc"
binding="wsHttpBinding" contract="IMyService">
<!-- To avoid disclosing metadata information,
set the value below to false and remove the
metadata endpoint above before deployment -->
<!-- To receive exception details in faults for
debugging purposes, set the value below to true.
Set to false before deployment to avoid disclosing exception information -->
Note:
You need to mention the service file name, along with the Address mention in the config file. IIS Screen shot
This screen will appear when we run the application.
Step 5: Now we successfully hosted the service in IIS. Next we have to consume this service in client application. Before creating the client application, we need to create the proxy for the service. This proxy is used by the client application, to interact with service. To create the proxy, run the Visual Studio 2008 command prompt. Using service utility we can create the proxy class and its configuration information.
svcutil http://localhost/IISHostedService/MyService.svc
After executing this command we will find two file generated in the default location.
- MyService.cs - Proxy class for the WCF service
- output.config - Configuration information about the service.
Step 6: Now we will start creating the Console application using Visual Studio 2008(Client application).
Step 7: Add the reference 'System.ServiceModel'; this is the core dll for WCF.
Step 8: Create the object for the proxy class and call the HelloWorld method.
static void Main(string[] args)
{
//Creating Proxy for the MyService
MyServiceClient client = new MyServiceClient();
Console.WriteLine("Client calling the service...");
Console.WriteLine(client.HelloWorld("Ram"));
Console.Read();
}
Step 9: If we run the application we will find the output as shown below.
Self Hosting
In web service, we can host the service only in IIS, but WCF provides the user to host the service in any application (e.g. console application, Windows form etc.). Very interestingly developer is responsible for providing and managing the life cycle of the host process. Service can also be in-pro i.e. client and service in the same process. Now let's us create the WCF service which is hosted in Console application. We will also look in to creating proxy using 'ClientBase'abstract class.
Note: Host process must be running before the client calls the service, which typically means you have to prelaunch it.
Step 1: First let's start create the Service contract and it implementation. Create a console application and name it as MyCalculatorService. This is simple service which return addition of two numbers.
Exercise:3
Step 2: Add the System.ServiceModel reference to the project.
Step 3: Create an ISimpleCalculator interface, Add ServiceContract and OperationContract attribute to the class and function as shown below. You will know more information about these contracts in later session. These contracts will expose method to outside world for using this service.
IMyCalculatorService.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
namespace MyCalculatorService
{
[ServiceContract()]
public interface ISimpleCalculator
{
[OperationContract()]
int Add(int num1, int num2);
}
}
Step 4: MyCalculatorService is the implementation class for IMyCalculatorService interface as shown below.
MyCalculatorService.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MyCalculatorService
{
class SimpleCalculator : ISimpleCalculator
{
public int Add(int num1, int num2)
{
return num1 + num2;
}
}
}
Step 5: Now we are ready with service. Let's go for implementing the hosting process. Create a new console application and name it as 'MyCalculatorServiceHost'
Step 6: ServiceHost is the core class use to host the WCF service. It will accept implemented contract class and base address as contractor parameter. You can register multiple base addresses separated by commas, but address should not use same transport schema.
Uri httpUrl
= new Uri("http://localhost:8090/MyService/SimpleCalculator");
Uri tcpUrl
= new Uri("net.tcp://localhost:8090/MyService/SimpleCalculator");
ServiceHost host
= new ServiceHost(typeof(MyCalculatorService.SimpleCalculator), httpUrl, tcpUrl);
Multiple end points can be added to the Service using AddServiceEndpoint() method. Host.Open() will run the service, so that it can be used by any client.
Step 7: Below code show the implementation of the host process.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Description;
namespace MyCalculatorServiceHost
{
class Program
{
static void Main(string[] args)
{
//Create a URI to serve as the base address
Uri httpUrl = new Uri("http://localhost:8090/MyService/SimpleCalculator");
//Create ServiceHost
ServiceHost host
= new ServiceHost(typeof(MyCalculatorService.SimpleCalculator), httpUrl);
//Add a service endpoint
host.AddServiceEndpoint(typeof(MyCalculatorService.ISimpleCalculator)
, new WSHttpBinding(), "");
//Enable metadata exchange
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
host.Description.Behaviors.Add(smb);
//Start the Service
host.Open();
Console.WriteLine("Service is host at " + DateTime.Now.ToString());
Console.WriteLine("Host is running... Press key to stop");
Console.ReadLine();
}
}
}
Step 8: Service is hosted, now we need to implement the proxy class for the client. There are different ways of creating the proxy
- Using SvcUtil.exe, we can create the proxy class and configuration file with end points.
- Adding Service reference to the client application.
- Implementing ClientBase class
Of these three methods, Implementing ClientBase is the best practice. If you are using rest two method, we need to create proxy class every time when we make changes in Service implementation. But this is not the case for ClientBase. It will create the proxy only at runtime and so it will take care of everything.
MyCalculatorServiceProxy.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using MyCalculatorService;
namespace MyCalculatorServiceProxy
{
public class MyCalculatorServiceProxy :
//WCF create proxy for ISimpleCalculator using ClientBase
ClientBase,
ISimpleCalculator
{
public int Add(int num1, int num2)
{
//Call base to do funtion
return base.Channel.Add(num1, num2);
}
}
}
Step 9: In the client side, we can create the instance for the proxy class and call the method as shown below. Add proxy assembly as reference to the project.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
namespace MyCalculatorServiceClient
{
class Program
{
static void Main(string[] args)
{
MyCalculatorServiceProxy.MyCalculatorServiceProxy proxy ;
proxy= new MyCalculatorServiceProxy.MyCalculatorServiceProxy();
Console.WriteLine("Client is running at " + DateTime.Now.ToString());
Console.WriteLine("Sum of two numbers... 5+5 ="+proxy.Add(5,5));
Console.ReadLine();
}
}
}
Step 10 : End point (same as service) information should be added to the configuration file of the client application.
<endpoint address ="http://localhost:8090/MyService/SimpleCalculator"
binding ="wsHttpBinding"
contract ="MyCalculatorService.ISimpleCalculator">
Step 11: Before running the client application, you need to run the service. Output of the client application is shown below.
This self host shows advantage such as in-Pro hosting, programmatic access and it can be used when there need singleton service. I hope you have enjoyed the Self hosting session, now let go for hosting using Windows Activation service.
Service Contract
Service contract describes the operation that service provide. A Service can have more than one service contract but it should have at least one Service contract.
Service Contract can be define using [ServiceContract] and [OperationContract] attribute. [ServiceContract] attribute is similar to the [WebServcie] attribute in the WebService and [OpeartionContract] is similar to the [WebMethod] in WebService.
- It describes the client-callable operations (functions) exposed by the service
- It maps the interface and methods of your service to a platform-independent description
- It describes message exchange patterns that the service can have with another party. Some service operations might be one-way; others might require a request-reply pattern
- It is analogous to the element in WSDL
To create a service contract you define an interface with related methods representative of a collection of service operations, and then decorate the interface with the ServiceContractAttribute to indicate it is a service contract. Methods in the interface that should be included in the service contract are decorated with the OperationContractAttribute.
[ServiceContract()]
public interface ISimpleCalculator
{
[OperationContract()]
int Add(int num1, int num2);
}
Once we define Service contract in the interface, we can create implement class for this interface.
public class SimpleCalculator : ISimpleCalculator
{
public int Add(int num1, int num2)
{
return num1 + num2;
}
}
With out creating the interface, we can also directly created the service by placing Contract in the implemented class. But it is not good practice of creating the service
[ServiceContract()]
public class SimpleCalculator
{
[OperationContract()]
public int Add(int num1, int num2)
{
return num1 + num2;
}
}
Data Contract
A data contract is a formal agreement between a service and a client that abstractly describes the data to be exchanged.Data contract can be explicit or implicit. Simple type such as int, string etc has an implicit data contract. User defined object are explicit or Complex type, for which you have to define a Data contract using [DataContract] and [DataMember] attribute.
A data contract can be defined as follows:
- It describes the external format of data passed to and from service operations
- It defines the structure and types of data exchanged in service messages
- It maps a CLR type to an XML Schema
- t defines how data types are serialized and deserialized. Through serialization, you convert an object into a sequence of bytes that can be transmitted over a network. Through deserialization, you reassemble an object from a sequence of bytes that you receive from a calling application.
- It is a versioning system that allows you to manage changes to structured data
Create user defined data type called Employee. This data type should be identified for serialization and deserialization by mentioning with [DataContract] and [DataMember] attribute.
[ServiceContract]
public interface IEmployeeService
{
[OperationContract]
Employee GetEmployeeDetails(int EmpId);
}
[DataContract]
public class Employee
{
private string m_Name;
private int m_Age;
private int m_Salary;
private string m_Designation;
private string m_Manager;
[DataMember]
public string Name
{
get { return m_Name; }
set { m_Name = value; }
}
[DataMember]
public int Age
{
get { return m_Age; }
set { m_Age = value; }
}
[DataMember]
public int Salary
{
get { return m_Salary; }
set { m_Salary = value; }
}
[DataMember]
public string Designation
{
get { return m_Designation; }
set { m_Designation = value; }
}
[DataMember]
public string Manager
{
get { return m_Manager; }
set { m_Manager = value; }
}
}Implementation of the service class is shown below. In GetEmployee method we have created the Employee instance and return to the client. Since we have created the data contract for the Employee class, client will aware of this instance whenever he creates proxy for the service.
public class EmployeeService : IEmployeeService
{
public Employee GetEmployeeDetails(int empId)
{
Employee empDetail = new Employee();
//Do something to get employee details and assign to 'empDetail' properties
return empDetail;
}
}
Client side
On client side we can create the proxy for the service and make use of it. The client side code is shown below.protected void btnGetDetails_Click(object sender, EventArgs e)
{
EmployeeServiceClient objEmployeeClient = new EmployeeServiceClient();
Employee empDetails;
empDetails = objEmployeeClient.GetEmployeeDetails(empId);
//Do something on employee details
}