Anatomy of Service Contract

In Windows Communication Foundation, a service contract declares a set of operations.

Minimal Code to Declare Service Contract

The following example declares service contract with minimal code.

 1 namespace BehavioralContractLibrary
 2 {
 3   using System.ServiceModel;
 4 
 5   [ServiceContract] // Note 1
 6   class MyService
 7   {
 8     [OperationContract] // Note 2
 9     public void PublicOperation() { }
10 
11     [OperationContract]
12     private /* Note 3 */ void PrivateOperation() { }
13 
14     public void IgnoredOperation() /* Note 4 */ { }
15   }
16 }
  • Note 1. Specifying ServiceContract attribute declares a class or interface as service contract.
  • Note 2. Specifying OperationContract attribute declares a member as service operation.  A service contract must specify at least one operation contract.  Otherwise, WCF throws this error at runtime -- System.InvalidOperationException: ContractDescription 'XXXX' has zero operations; a contract must have at least one operation..
  • Note 3. Class accessibility does not restrict service operation declaration.
  • Note 4. Members without OperationContract attribute are excluded from service operation.

For illustrative purpose, the code above declares service contract to a class. However, it’s ideal to declare service contract among interface. Using interface as a layer of abstraction allows degree of flexibility to service definition in the long run.

Specifying Name and Namespace

Namespace and name can be declared explicitly at various sections.

 1 namespace BehavioralContractLibrary
 2 {
 3   using System.ServiceModel;
 4 
 5   [ServiceContract(/* Note 1 */ Name = "MyMessageParameter",
 6                    /* Note 2 */ Namespace = "http://wcf.kenwon.org/2011/01")]
 7   interface IMessageParameter
 8   {
 9     [OperationContract(/* Note 3 */ Name = "MyOperation")]
10     void NamedOperation();
11 
12     [OperationContract]
13     /* Note 4 */
14     [return: MessageParameter(Name = "ResponseValue")]
15     string NamedResponseOperation();
16 
17     [OperationContract]
18     void NamedRequestOperation(/* Note 5 */ [MessageParameter(Name = "Request")]
19                                string input);
20   }
21 }
  • Note 1.  Name property declares service contract name.
  • Note 2.  Namespace property declares service contract name.
  • Note 3.  Name property declares operation contract name.
  • Note 4.  MessageParameterAttribute declares return parameter name.
  • Note 5.  MessageParameterAttribute declares input parameter name.

Minimal Code to Declare REST Oriented Service Contract

WCF is originally designed for SOAP based operation. However, it’s also easy to declare for REST based operation.

 1 namespace BehavioralContractLibrary
 2 {
 3   using System.ServiceModel;
 4   using System.ServiceModel.Web;
 5 
 6   [ServiceContract]
 7   public class MyRestfulService
 8   {
 9     /* Note 1 */ [WebGet]
10     public void GetOperation() { }
11 
12     /* Note 2 */ [WebInvoke]
13     public void InvokeOperation() { }
14   }
15 }
  • Note 1.  Specifying WebGetAttribute attribute declares a service operation on HTTP GET method.
  • Note 2.  Specifying WebInvokeAttribute attribute declares a service operation on HTTP POST method.  Other HTTP verbs can be handled from Method property.

Programming Language Specific Issues

Handling Overloaded Methods

Overloaded methods (same method name, different parameters and/or return type) are object-oriented construct.  In service-oriented construct, this can be done by renaming method name.  Otherwise, WCF throws this exception at runtime.

System.InvalidOperationException: Cannot have two operations in the same contract with the same name

 1 namespace BehavioralContractLibrary
 2 {
 3   using System.ServiceModel;
 4 
 5   [ServiceContract]
 6   class MyOverloadedService
 7   {
 8     [OperationContract(Name = "Op1")]
 9     public void Operation(int input) { }
10 
11     [OperationContract(Name = "Op2")]
12     private void Operation() { }
13   }
14 }

Out and Ref Parameters

Unless the underlying binding does not support out (ByVal) and ref (ByRef), service contract uses the parameters as returns value.

 1 namespace BehavioralContractLibrary
 2 {
 3   using System.ServiceModel;
 4 
 5   [ServiceContract]
 6   interface IMyRefOutService
 7   {
 8     [OperationContract]
 9     void OperationWithRef(/* Note 1 */ ref int input);
10 
11     [OperationContract]
12     /* Note 2 */int OperationWithRefAndReturn(ref int input);
13 
14     [OperationContract]
15     void OperationWithOut(/* Note 3 */ out int input);
16 
17     [OperationContract]
18     /* Note 4 */int OperationWithOutAndReturn(out int input);
19 
20     [OperationContract]
21     int OperationWithReturn(int input);
22   }
23 }
  • Note 1.  ref parameter is served as return value.
  • Note 2.  Both return parameter and ref parameter are served as return value.
  • Note 3.  out parameter is served as return value.
  • Note 4.  Both return parameter and out parameter are served as return value.

Additional Features

Here’re other specifications relevant to service contract.

  • Message Exchange Pattern (MEP) specifies service operation request and response message behavior.  Message Exchange Pattern
  • Fault contracts specifies exception error propagation behavior.  Fault Contract

Further Study

Reference