Praveen Katiyar' Blog

Learning along the way . . . .

Introduction to WCF

What is WCF

In a nutshell, WCF is a SDK for developing and deploying services on Windows, although services can be build even without WCF.  Developing services with WCF is easier. WCF is Microsoft’s implementation of a set of industry standards defining service interactions, type conversions, marshaling, and management of various protocols. consequently, WCF provides interoperability between services.    

What is SOA

SOA is the next evolutionary step in the long journey from functions to object to components to service orientated applications. Service orientation (SO) is an abstract set of methodologies, principles and best practices for building service oriented applications(SOA). Service oriented application aggregates services into a single logical application.

What is a Service

A service is a unit of functionality exposed to the world. the services can be local or remote, can be deployed by multiple parties using any technology.

What is a WCF Service

WCF Service typically exposes metadata describing the available functionality and possible ways of communicating with service. Metadata is published in a predefined, technology-neutral way such as using WSDL (Web Services Description Language) over HTTP-GET or an industry standard for metadata exchange over any protocol. WCF services may communicate over a variety of transports (not just HTTP). A non WCF client can import the metadata to its native environment as native types. similarly, a WCF client can import the metadata of a non WCF service and  consume it as a native CLR class/interface. 

Anatomy of WCF Service/ A B C of WCF Service

(A) Address

in WCF every service is associated with a unique address. the address provides two important elements:

  • location of the service: the location portion of the address indicates the name of the target machine, site, or network; a communication port, pipe or queue; and an optional specific path, or URI. URI can be any unique string, such as service name or a globally unique identifier (GUID).

  • transport protocol/transport scheme: WCF supports following transport protocols/schemes.

    • HTTP/HTTPS

    • TCP

    • IPC

    • Peer network

    • MSMQ

    • Service Bus

the address always have the following format

[base address] / [optional URI]

the base address is always in the format

[transport]://[machine or domain][optional port]

here are few examples of  sample addresses.

http://localhost:8001                              

http://localhost:8001/MyService           

net.tcp://localhost:8002/MyService      

net.pipe://localhost/MyPipe                   

net.msmq://localhost/MyQueue             

here are few examples of  sample addresses.

(B) Binding

A binding is merely, a consistent, canned set of choices regarding the transport protocol, message encoding, communication pattern, reliability, security, transaction propagation and interoperability. A single service can support multiple bindings on separate addresses. Binding allow you to use the same service logic over drastically different plumbing. all you need to do is determine the target scenario for your service, and WCF makes a correct multidimensional decision for you regarding all the aspects of the communication. One can use the WCF-provided bindings out of the box, can tweak their properties, or can write their own custom bindings from scratch. WCF defines 5 frequently used bindings.

  • Basic Binding: offered by the BasicHttpBinding class, basic binding is designed to expose a WCF services as a legacy ASMX web service, so that old clients can work with the new services. this binding makes your service look like a legacy web service that communicates over basic web service profile. when used by clients, this enables new WCF clients to work with old ASMX services.
  • TCP Binding:  offered by NetTcpBinding class, TCP binding uses TCP for cross machine communication on the intranet. it supports variety of features, including reliability, transactions and security, and is optimized for WCF to WCF communication, hence it requires both the client and the service to use WCF.
  • IPC Binding: offered by NetNamedPipeBinding class, IPC binding uses named pipes as a transport for same-machine communication. it is the most secure binding, since it can not accept calls outside of the machine boundary. It is also the most performant binding, since IPC is a lighter protocol than TCP.
  • Web Service (WS) Binding: offered by WSHttpBinding class, the WS binding uses HTTP or HTTPS for transport and offers a variety of features(such as reliability, transactions, and security) over the Internet, all using the WS-* standards.
  • MSMQ Binding: offered by the NetMsmqBinding class, the MSMQ binding uses MSMQ for transport and offers support for disconnected queued calls. 

each frequently used binding  uses different transport scheme and encoding as shown below.

Name Transport Encoding Interoperable
BasicHttpBdinding HTPP/HTTPS TEXT, MTOM Yes
NetTcpBinding TCP Binary No
NetNamedPipeBinding IPC Binary No
WsHttpBinding HTTP/HTTPS TEXT, MTOM Yes
NetMsmqBidning MSMQ Binary No

having text based encoding typically enables a WCF service (or client) to communicate over HTTP with any other service (or client), regardless of its technology and across firewalls. Binary encoding over TCP, IPC or MSMQ yields the best performance, but it does so at the cost of interoperability because it mandates the WCF-WCF communication.

Choosing a Binding

When choosing a binding the following diagram can help.

image

in addition to the five frequently used bindings described above, WCF defines 6 infrequently used bindings. these bindings are each designed for a specific target scenario, which normally can not be used out of that scenario. 

  • WS dual binding:  offered by WSDualHttpBinding class, similar to the WS binding, except it also supports bidirectional duplex communication from the service to the client. This binding nothing more than just two WsHttpBinding bindings wired up against each other to support callbacks, as there is no industry standard for setting up callback, thus WSDualHttpBinding is not interoperable.
  • Peer Network binding: offered by NetPeerTcpBinding class, this uses peer networking as a transport: the peer network enabled client and services all subscribe to the same grid and broadcast messages to it.
  • Fedrated WS binding: offered by WSFedrationHttpBinding class, a specialization of WS binding that offers support for federated security, not a main stream binding. 
  • Fedrated WS 2007 binding: offered by WS2007FedrationHttpBinding class, this is an update of a WSFedrationHttpBinding.
  • MSMQ integration binding: offered by MSMQIntegrationBinding class, this is the analogous queued –world binding to the basic binding. The integration binding converts WCF messages to and from MSMQ messages and is designed to interoperate with legacy MSMQ clients.
  • WS 2007 binding: offered by WS2007HttpBinding class, this binding is derived from the WSHttpBinding class; it adds support for the emerging co-ordination standard and updates for the transaction, security, and reliability standards.

(C) Contracts

A WCF contract is a platform neutral and standard way of describing what a service does. in WCF all services expose contracts. WCF defines 4 types of contracts.

  • Service Contracts: Describes which related operations can be tied together as a single functional unit that the client can perform on the service. Service contracts can be defined as shown below.

    [ServiceContract]
    public interface IMyService
    {

    }

  • Operation Contract: An operation contract defines the parameters and return type of an operation.

    [ServiceContract]
    public interface IMyService
    {
       [OperationContract]
        double MultiplyNumber(double dblX, double dblY );   
       [OperationContract]
        double DivideNumber(double dblX, double dblY );  
    }

  • Data Contracts: Defines which data types are passed to and from the service. WCF defines implicit contracts for built in types such as int and string, but you can easily define explicit opt in data contracts for custom types.

    [DataContract]
    public class ErrorInfo
    {
        private string m_strError;
        private int m_nErrorCode;
       
       [DataMember]
        public string ErrorMessage
        {
            get { return m_strError; }
            set { m_strError = value; }
        }

       [DataMember]
        public int ErrorCode
        {
            get { return m_nErrorCode }
            set { m_nErrorCode = value; }
        }
    }

  • Fault Contracts: Defines which errors are raised by the service and how the service handles and propagates errors to the clients. Fault Contract provides documented view for error occurred in the service to client. This helps to easily identity the error.

    [ServiceContract]
    public interface IMyService
    {
        [OperationContract]
        double MultiplyNumber(double dblX, double dblY );   
        [OperationContract]
       [FaultContract(typeof(DevideByZeroException))]
        double DivideNumber(double dblX, double dblY );  
    }

  • Message Contracts: Allow the service to interact directly with messages. Message contracts can be types or un typed and are useful in interoperability cases when another party has already dictated some explicit (mostly proprietary) message format. 

    [MessageContract]
    public class ErrorDetails
    {
        [MessageHeader]
        public int  ErrorCode;
       
       [MessageBodyMember]
        public string ErrorMessage;
       [MessageBodyMember]
        public DateTime ErrorTime;
    }

Hosting

The WCF service class can not exist in void. every WCF service must be hosted in a Windows process called host process. a single host process can host multiple services, and the same service type can be hosted in multiple services.

Hosting Environment and Supported Bindings

Hosting Environment

Supported protocol

Windows console and form application

http, net.tcp, net.pipe, net.msmq

Windows service application (formerly known as NT services)

http, net.tcp, net.pipe, net.msmq

Web server IIS6

http, wshttp

Web server IIS7 – Windows Process Activation Service (WAS)

http, net.tcp, net.pipe, net.msmq

 

A summary of hosting options and supported features.

Feature

Self-Hosting

IIS Hosting

WAS Hosting

Executable Process/ App Domain

Yes

Yes

Yes

Configuration

App.config

Web.config

Web.config

Activation

Manual at startup

Message-based

Message-based

Idle-Time Management

No

Yes

Yes

Health Monitoring

No

Yes

Yes

Process Recycling

No

Yes

Yes

Management Tools

No

Yes

Yes

Endpoints

Every service is associated with an address that defines where the service is, a binding defines how to communicate with the service, and the contract defines what the service does. WCF formalizes this relationship in the form of endpoint. The endpoint is the coalition of address, binding and contract. So every endpoint must have all 3 elements, and the host exposes the endpoint. logically, endpoint is the interface of the service to the outside world. Every service must expose at least one business Endpoint, and each endpoint has exactly one contract. All endpoints on a service has unique addresses, and a single service can expose multiple endpoints.

Configuration of Endpoint

It is important to note nothing in the service code has to do with its service points. and they are always external to the service code. you can configure endpoints either administratively or programmatically.

Administrative Endpoint Configuration

<system.ServiceModel>
    <services>
        <service name="MyService">
            <endpoint address="http://localhost:8000/MyService&quot; binding ="wsHttpBinding" contract="IMyContract">
            <endpoint address="http://localhost:8001/MyService&quot; binding ="netTcpBinding" contract="IMyContract">
            <endpoint address="http://localhost:8002/MyService&quot; binding ="netTcpBinding" contract="IOtherContract">
        </service>
    </services>
</system.ServiceModel>

Programmatic Endpoint Configuration

ServiceHost host = new ServiceHost(typeof(MyService));
Binding httpBinding = new WSHttpBinding();
Binding tcpBinding = new NetTcpBinding();
host.AddServiceEndPoint( typeof (IMyContract), httpBinding, "
http://localhost:8000/MyService");
host.AddServiceEndPoint( typeof (IMyContract), tcpBinding, "net.tcp://localhost:8001/MyService");
host.AddServiceEndPoint( typeof (IMyOtherContract), tcpBinding, "net.tcp://localhost:8002/MyService");

Default Endpoints

If the service host does not define any end points (neither in configuration nor programmatically) but does provide at least one base address. WCF will by default add endpoints to the service. These are called default endpoints. WCF will add an endpoint per base address per contract, using the base address as the endpoint’s address. for HTTP WCF will use the basic binding. Note that default binding will affect the default endpoints. WCF will also name the endpoint by concatenating the binding name and the contract name.

consider the following example.

[ServiceContract]
interface IMyContract {
    //Interface Body
    … 
}

[ServiceContract]
interface IMyOtherContract {
    //Interface Body
    … 
}

class MyService : IMyContract, IMyOtherContract {
    //Class Body
    … 
}

//    Host Application
Uri httpbaseAdr = new Uri ( "http://localhost:8000/");
Uri tcpbaseAdr = new Uri ( "net.tcp://localhost:9000/");
Uri pipebaseAdr = new Uri ( "net.pipe://localhost/");
ServiceHost host = new ServiceHost ( typeof (MyService), httpbaseAdr, tcpbaseAdr, pipebaseAdr);
host.Open ();

Assuming that no config file is used to define any additional endpoints, WCF will add these default endpoints, as they were defined in config file.

<service name="MyService">


    <endpoint name="BasicHttpBinding_IMyContract" address="http://localhost:8000/" binding="basicHttpBinding" contract="IMyContract" />
    <endpoint name="NetTcpBinding_IMyContract" address="net.tcp://localhost:9000/" binding="netTcpBinding" contract="IMyContract" />
    <endpoint name="NetNamedPipeBinding_IMyContract" address="net.pipe://localhost/" binding="netNamedPipeBinding" contract="IMyContract" />
   
    <endpoint name="BasicHttpBinding_IMyOtherContract" address="http://localhost:8000/" binding="basicHttpBinding" contract="IMyOtherContract" />
    <endpoint name="NetTcpBinding_IMyOtherContract" address="net.tcp://localhost:9000/" binding="netTcpBinding" contract="IMyOtherContract" />
    <endpoint name="NetNamedPipeBinding_IMyOtherContract" address="net.pipe://localhost/" binding="netNamedPipeBinding" contract="IMyOtherContract" />

</service>   

Metadata Exchange

By default, the service will not publish its metadata. publishing you service meta data will need some efforts. , luckily, the host can do it for you, if you instruct it to do so, as host knows everything, it needs to know about your service and its endpoints.

Enabling Metadata exchange administratively

<system.ServiceModel>
<services>
    <service name="MyService" behaviorConfiguration="MEXGET">
        <host>
        <baseAddresses>
            <add baseAddress = "net.pipe://localhost/" /> 
        </baseAddresses>
        
         <endpoint address="MEX" binding="mexNamedPipeBinding" contract="IMetadataExchange"/>

        <!– Here we have defined the complete address, we do not use the base address. -–>
        <endpoint address="http://localhost:8000/MEX" binding="mexHttpBinding" contract="IMetadataExchange"/>

        <endpoint address="net.tcp://localhost:8001/MEX" binding="mexTcpBinding" contract="IMetadataExchange"/>

    </service>   
</services>
</system.ServiceModel>

in the vast majority of cases, a MEX endpoint always has the same 3 elements: the contract is always IMetadataExchange, the binding is always the reserved binding element, and the only variable is the address (and that too, just the base address)

Adding MEX endpoints programmatically

like any other endpoint, you can also add metadata exchange endpoint programmatically before opening the host. WCF does not offer a dedicated binding type for the metadata exchange endpoint. you can use the following methods of MetadataExchangeBindings  class defined in System.ServiceModal.Description

Uri tcpbaseAdr = new Uri ( “net.tcp://localhost:9000/”);
ServiceHost host = new ServiceHost ( typeof (MyService), tcpbaseAdr );
ServiceMetadataBehavior metaBehave ;
metaBehave = host.Description.Behaviors.Find<ServiceMetadataBehavior>();
if ( metaBehave == null )
{
    metaBehave = new ServiceMetadataBehavior();
    host.Description.Behaviors.Add (metaBehave);
}
Binding binding = MetadataExchangeBindings.CreateMexTcpBinding ();
host.AddServiceEndpoint (typeof (IMetadataExchange), binding, "MEX");
host.Open ();

you can also add a MEX endpoint using the standard MEX endpoint.

ServiceHost host = new ServiceHost (typeof(MyService));
host.Description.Behaviors.Add(new ServiceMetadataBehavior());
EndpointAddress address = new EndpointAddress ( "
http://localhost:8000/MEX");
ServiceEndPoint endpoint = new ServiceMetadataEndPoint(address) ;
host.AddServiceEndpoint (endpont);
host.Open ();

Client side Programming

To invoke operations on a service, a client first need to import the service contract to client’s native (environ.) .

Client side Calling Service using Code

Just define the interface definition in the client application in a file, say IMyService.cs.

[ServiceContract]
public interface IMyService
{
   [OperationContract]
    double AddNumber(double dblX, double dblY );   
   [OperationContract]
    double MultiplyNumber(double dblX, double dblY );   
}

assuming that Service is hosted at address “http://localhost:8001/MyService/”

To invoke operations on a service, if you do not want to use a configuration file. a client need to create everything by hand.

private void CallServiceFunctionOnHTTP ()
{
    string strAdr =
http://localhost:8001/MyService/”;
    Uri adrbase = new Uri(strAdr);
    BasicHttpBinding httpb = new BasicHttpBinding();
    ChannelFactory<IMyService> channelFactory = new ChannelFactory<IMyService>(httpb);
   
    strEPAdr = "
http://localhost:8001/MyService" ;
    EndpointAddress ep = new EndpointAddress(strEPAdr );
    IMyService myObj = m_ChannelFactory.CreateChannel(ep);
    double dblResult = 0;
    dblResult = chatObj.AddNumber(dblX, dblY);
}

If the same Service also exposes another EndPoint (let say at "net.tcp://localhost:9000/MyService” ) then you can call the service, through this end point as shown below.

private void CallServiceFunctionOnTCP ()
{
    string strAdr =
net.tcp://localhost:9000/MyService/”;
    Uri adrbase = new Uri(strAdr);
    NetTcpBinding tcpb = new NetTcpBinding();
    ChannelFactory<IMyService> channelFactory = new ChannelFactory<IMyService>(tcpb);
   
    strEPAdr = "
net.tcp://localhost:9000/MyService
" ;
    EndpointAddress ep = new EndpointAddress(strEPAdr );
    IMyService myObj = m_ChannelFactory.CreateChannel(ep);
    double dblResult = 0;
    dblResult = chatObj.AddNumber(dblX, dblY);
}

Advertisements

August 20, 2013 - Posted by | .NET, CodeProject, SOA, WCF | , , , ,

No comments yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: