Chapter 2. Service Contracts
Chapter 2. Service Contracts
Service Contracts
A service contract describes the operations a service can perform. A service must have at least one
service contract, and it can have more than one. You can think of a service contract as follows:
It describes the client-callable operations (functions) your service provides.
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.
1. A Service can have more than one service contract but it should have at least one Service
contract
2. can be define using [ServiceContract] and [OperationContract] attribute
3. [ServiceContract] attribute is similar to the [WebServcie] attribute in the WebService
4. and [OpeartionContract] is similar to the [WebMethod] in WebService.
5. [ServiceContract]
6. public interface IReservation
7. {
8. [OperationContract]
9. string StartReservation(string lastName, string firstName);
10. [OperationContract]
11. bool ReserveRoom(string arriveDate, string departDate, int guests);
12. [OperationContract]
13. string ConfirmReservation(bool authorize);
14. }
Once you define a service contract using an interface, you can write a class to implement the interface.
For example:
public class Reservation : IReservation
{
public string StartReservation(string lastName, string firstName)
{
...
}
public bool ReserveRoom(string arriveDate, string departDate, int guests)
{
...
}
public string ConfirmReservation(bool authorize)
{
...
}
}
If you don't like using interfaces, you can instead define the service contract directly against the
implementation class and skip the interface altogether. The following class both defines and
implements a service contract.
[ServiceContract]
public class Reservation
{
[OperationContract]
public string StartReservation(string lastName, string firstName)
{
...
}
[OperationContract]
public bool ReserveRoom(string arriveDate, string departDate, int guests)
{
...
}
[OperationContract]
public string ConfirmReservation(bool authorize)
{
...
}
}
A service contract can specify requirements that must be satisfied by endpoint bindings.
The [BindingRequirements]attribute specifies binding requirements for the contract. The following
service contract specifies a requirement for ordered delivery of messages.
[ServiceContract]
[BindingRequirements(RequireOrderedDelivery=true)]
public interface IReservation
{
[OperationContract]
string StartReservation(string lastName, string firstName);
[OperationContract]
bool ReserveRoom(string arriveDate, string departDate, int guests);
[OperationContract]
string ConfirmReservation(bool authorize);
}
You can specify the following parameters in any order for the [ServiceContract] attribute:
CallbackContract (type)
References a client callback contract used for duplex communication. The default is no
callback contract.
FormatMode (ContractFormatMode)
Selects a serializer. A serializer is a class used to perform serialization and deserialization. You
can set this property to XmlFormatter or XmlSerializer. The default is XmlFormatter.
Name (string)
Specifies the name of the service contract. If this parameter is omitted, the default is the
interface name.
Namespace (string)
Specifies the namespace of the service contract. If this parameter is omitted, the default is the
interface namespace.
Session (boolean)
Style (ServiceOperationStyle)
Determines how the WSDL metadata for the service is formatted. Possible values
are DocumentWrapped,DocumentBare, and Rpc. The default is DocumentWrapped. This
property also exists at the [OperationContract]level.
Use (ServiceOperationBindingUse)
If the client and service implement identical contracts, there is no need to define a second contract.
The service contract can reference itself in the CallbackContract parameter.
[ServiceContract(CallbackContract=typeof(IChat))]
public interface IChat
{
[OperationContract]
void Say(string from, string text);
}
Identifies the action to be performed by the service operation. If Action is not specified, the
default ishttp://tempuri.org/contract-name/operation-name. In an untyped service, you can
set Action to * to intercept all service operations.
AsyncPattern (boolean)
IsInitiating (boolean)
Determines whether a service operation initiates a new channel on the service. The default
is true (yes).
IsOneWay (boolean)
Defines the service as one-way or two-way. A one-way service does not send a response and
might not have a return type other than void. A two-way service is accessed in a request-reply
pattern. The default is false(two-way).
IsTerminating (boolean)
Determines whether a service operation will close and shut down the client channel after the
service operation completes and replies. The default is false (no).
Name (string)
Specifies the name of the service operation. The default is the method name of the service
operation.
ReplyAction (string)
Identifies the action of the response sent by the service operation. If ReplyAction is not
specified, the default ishttp://tempuri.org/contract-name/operation-nameResponse.
Style (ServiceOperationStyle)
Specifies how the WSDL metadata for the service is formatted. Possible values
are DocumentWrapped,DocumentBare, and Rpc. The default is DocumentWrapped. This
property also exists at the [ServiceContract]level and is described in that section of the
chapter.
Use (ServiceOperationBindingUse)
In an untyped service operation, you can set Action to * to intercept all messages.
[ServiceContract]
public interface IMyUntypedContract
{
[OperationContract(IsOneWay=false, Action="*")]
Message ProcessMessage(Message message);
}
The Begin operation has two additional parameters beyond what the service operation normally
requires:AsyncCallback and a state object. The Begin operation returns an IAsyncResult rather than
what the service operation would normally return. The End operation accepts
an IAsyncResult parameter and returns the service operation result.
For information on using the Async Pattern in clients, see Chapter 6. For information on implementing
the Async Pattern in service operations, see Chapter 7.
IsInitiating and IsTerminating: Controlling Session Lifetime
Services can provide session instancing, in which a separate instance of the class is maintained for
each client channel. The IsInitiating and IsTerminating parameters allow you to control which service
operations initiate or terminate a session instance. By default, all service operations initiate a session
instance. In the following service contract, the OpenAccount service operation initiates the sessions
and must be the first service operation a client calls. The CloseAccount service terminates the session.
[ServiceContract]
public interface IBanking
{
[OperationContract(IsInitiating=true, IsTerminating=false)]
void OpenAccount(account);
[OperationContract(IsInitiating=false, IsTerminating=false)]
void Deposit(decimal amount);
[OperationContract(IsInitiating=false, IsTerminating=false)]
void Withdraw(decimal amount);
[OperationContract(IsInitiating=false, IsTerminating=true)]
void CloseAccount();
}
QueuedDeliveryRequirements (RequirementsMode)
RequireOrderedDelivery (boolean)
Specifies whether ordered delivery of messages is required. Possible values are true and false.
The default isfalse, which means ordered delivery is not required.
TransactionFlowRequirements (RequirementsMode)
Typed message In a typed message service, the parameters and return values of service
operations are custom messages defined with message contracts.
Defining Typed Service Operations
A typed service operation is one that accepts simple or complex data as parameters and return values.
Using a typed service operation feels very much like using a method of a class. The following service
contract contains typed service operations.
[ServiceContract]
public interface IMeasurementConversion
{
[OperationContract]
float CalculateDistance(float x1, float y1, float x2, float y2);
[OperationContract]
int CalculateShippingZone(float x1, float y1);
}
Service operations can return values, as the preceding service operations do. But sometimes you
might need to return more than one value or return a modified version of a parameter value. In these
cases, you can use ref andout parameters, just as you would in object-oriented programming. In
actuality, you are passing by value. The following service operations use ref and out parameters.
[ServiceContract]
public interface IMeasurementConversion
{
[OperationContract]
void MoveNorth(ref float x, ref float y, float distance);
[OperationContract]
void MoveSouth(ref float x, ref float y, float distance);
[OperationContract]
void MoveEast(ref float x, ref float y, float distance);
[OperationContract]
void MoveWest(ref float x, ref float y, float distance);
[OperationContract]
void CalculateDistance(float x1, float y1, float x2, float y2, out float
distance);
}
In addition to simple types and arrays, typed service operations can also accept complex data
structures as parameters or return them as results. This requires the use of data contracts. See the
earlier section titled "Understanding Data Contracts" and the later section titled "Programming Data
Contracts" for more information.
Defining Untyped Service Operations
An untyped service operation accepts a Message parameter, which allows it to accept any kind of
incoming message. The service operation code is responsible for interpreting the message. If the
service operation sends a reply, it is also of type Message. The following service contract contains an
untyped service operation.
[ServiceContract]
public interface IMyUntypedContract
{
[OperationContract(IsOneWay=true, Action="*")]
void ProcessMessage(Message message);
}
[MessageContract]
public class Contact
{
[MessageHeader]
string LastName;
[MessageHeader]
string FirstName;
[MessageBody]
string Phone;
[MessageBody]
string Email;
[MessageBody]
string Notes;
}
For information on how to create message contracts, see the section titled "Programming Message
Contracts" later in this chapter. For information on how to implement typed message service
operations, see Chapter 7.