Saturday, March 6, 2010

WCF Contracts

In this blog we will be looking into WCF (Windows Communication Foundation) message exchange patterns (MEP). WCF is the one for all framework for communication needs in distributed applications. Communicating data between the applications needs a careful implementation of message exchange pattern. It defines the way in which the communication will proceed. WCF provides the way to define the MEP using the contracts , that explains to both client and the host the way in which the communication will be initiated.

First of MEP is Request-Reply pattern. This pattern allows two side to exchange
the messages , but the requesting side have to wait for the response.

[ServiceContract]
public interface IRequestReplyContract
{
[OperationContract]
string Reply(string request);
[OperationContract]
string Get(string setMessage);
}

Even though if the signature of the method in Request-Reply pattern is of void
return type, the WCF infrastructure will return empty message to specify the return of response from called method.Inorder to stop return of empty message, we have to use OneWay operation contract attribute to define that the MEP is strictly one-way
exchange pattern.
.

One-Way:-


[ServiceContract]
public interface IOneWayContract
{
[OperationContract(IsOneWay = true)]
void OneWayMessage(string message);

[OperationContract(IsOneWay = true)]
void OneWayCall(string callParameter);
}

The One-Way contract is used to dispatch messages to all the subscriber's without waiting for any kind of response from the subscribers.One-Way contract is also used with Duplex contract for two way communication.

Duplex Contract:-


[ServiceContract(CallbackContract = typeof(IDuplexCallBackContract))]
public interface IDuplexContract
{
[OperationContract(IsOneWay = true)]
void SendServerMessage(string message);

[OperationContract(IsOneWay = true)]
void SendServerAuthInfo(string authMessage);
}

Duplex contract uses two contracts that are used by both
client and the host to initiate two way full duplex communication.

public interface IDuplexCallBackContract
{
[OperationContract(IsOneWay = true) ]
void SendClientMessage(string message);

[OperationContract(IsOneWay = true)]
void SendClientAuthMessage(string message);
}





WCF can send messages using either buffered or streamed mode.Buffered mode expects
the message to be fully delivered before the receiver can read it. In streamed mode
the receiver can start processing sent messages same time as the host starts
delivering the messages.When messages are too large and can be processed serially then the streamed mode is used.


[ServiceContract]
public interface IStreamedContract
{
[OperationContract]
Stream DownLoadFile(string fileName);

[OperationContract]
bool UploadFile(Stream stream);
}





public static Binding CreateStreamingBinding()
{
BasicHttpBinding b = new BasicHttpBinding();
b.TransferMode = TransferMode.Streamed;
return b;
}

Streaming has to be enabled at transport level.The parameter that holds the data to be streamed has to be only paramter and it should be of type Message, Stream or IXmlSerializable. Streaming must be enabled in the binding using TransferMode
property, that has four options (Buffered, Streamed,StreamedRequest,
StreamedResponse).

When more complex data has to be passed through the WCF infrastructure , we use DataContracts with the DataMember attribute on methods exposed.

[ServiceContract]
public interface IDataContractUsage
{
[OperationContract]
void SetInfo(Info information);
}

//System.Runtime.Serialization
[DataContract]
public class Info
{
[DataMember]
public string Name{get;set;}

[DataMember]
public string Address { get; set; }

[DataMember]
public string City{get; set;}

[DataMember]
public string Mail { get; set; }
}



WCF also allows communication to be session specific.All the message passed in
between are part of a single conversation. Unlike the sessions used in the asp.net
WCF session does not use any store for session specific data.Sessions in WCF are
only initiated by the calling application and are processed in the order in which
they arrive.

[ServiceContract(SessionMode = SessionMode.Allowed)]
public interface ISessionContract
{
[OperationContract(IsOneWay = true, IsInitiating= true, IsTerminating = false)]
void InitiateSession();

[OperationContract(IsOneWay = true, IsInitiating= false, IsTerminating = false)]
string SendMessage(string message);

[OperationContract(IsOneWay = true, IsInitiating = false, IsTerminating = true)]
void EndSession();
}



Session Mode property of the Session Contract attribute defines the kind of session
to initiate.It has values Allowed, Required, NotAllowed.
WCF also support transactions for all message communication.To enable transactions we
have to specify the TransactionIsolationLevel property in the ServiceBehavior
attribute applied to the class that implement the Service contract.

[ServiceContract]
public interface ITransactionContract
{
[OperationContract]
double CalculateMarketAverage();

[OperationContract]
double CalculateMarketHighestPurchase();
}

//Implementation of the transacion scope:.
// Add assembly System.Transaction
[ServiceBehavior(TransactionIsolationLevel = System.Transactions.IsolationLevel.Serializable)]
public class TransactionContract: ITransactionContract
{
[OperationBehavior(TransactionScopeRequired = true,
TransactionAutoComplete = true)]
public double CalculateMarketAverage()
{
}
}
//Client side use of the Servcie.
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.RequiresNew))
{
//Operation of service called here
}

<-binding name="netTcpBindingWSAT"
transactionFlow="true"
transactionProtocol="WSAtomicTransactionOctober2004" >


Apart from defining the contracts for MEP ,a lot of time is also spent on the
configuration of WCF bindings, behaviours and addresses.