Instance Context Mode in WCF

This article will show Instance Context modes in WCF.

Introduction

The understanding of this article requires an understand of some basics regarding WCF. Once again this will be an article for beginners in WCF to understand instancing.

Context Modes are very confusing for developers to understand and use. Although many articles exist in the web, I was thinking whether I should write one. I decided to write this article in simpler language and more explanatory for beginners to learn Instancing.

An Instance Context mode defines how long a service instance remains on the server.

Request Response Cycle


Whenever the client sends a request to a WCF service, what exactly happens behind the scenes? Basically after making a client request the WCF service will create a service class instance at the service that will do the operations involved and then it will return the response back to the client. In this request and response process the service instance object has been created in the process. Now the question arises, what will be the scope of that object or lifetime of that instance?

Here comes the concept of Instance Context mode in WCF.

The WCF framework has defined the following three Instance Context modes:

PerCall: a new instance of the service will be created for the request from the same client or a different client, meaning every request is a new request. In this mode no state is maintained.

PerSession: a new Instance will be created for every new client session and the scope of that object will be the scope of that session.

Single: a single instance will be created for the service object that will take care of all the requests coming from the same client or a different one.
By decorating the service with a service behavior, an Instance Context mode can be set.

  1. [ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCall)]   


PerCall Mode: a new instance of a service will be created for the request from the same client or a different client, meaning it will take every request as a new request.

Sample Code: Per Session Sample code with service, client and configuration.

Service Code
  1. IOrderService  
  2.   
  3. namespace CustomerOrderService  
  4. {    
  5.     [ServiceContract]  
  6.     public interface IOrderService  
  7.     {  
  8.         [OperationContract]  
  9.         int GetCallCount();  
  10.           
  11.         [OperationContract]  
  12.         Customer GetCusomersDetails(int ID);  
  13.   
  14.         [OperationContract]  
  15.         void UpdateCustomers(int ID);  
  16.   
  17.         [OperationContract]  
  18.         void AddCustomers(Customer cust);  
  19.   
  20.     }      
  21. }  
Order Service

  1. namespace CustomerOrderService  
  2. {  
  3.     [ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCall)]  
  4.     
  5.   public class OrderService : IOrderService  
  6.     {  
  7.         Customer cust = null;  
  8.         private int _callCount;                              Instance Context Mode        
  9.         public int GetCallCount()  
  10.         {  
  11.             _callCount=_callCount+1;  
  12.             return _callCount;  
  13.         }  
  14.   
  15.        public Customer GetCusomersDetails()  
  16.         {  
  17.              throw new NotImplementedException();  
  18.   
  19.          }  
  20.   
  21.         public void AddCustomers(Customer cust)  
  22.         {  
  23.             throw new NotImplementedException();  
  24.         }  
  25.   
  26.         public Customer GetCusomersDetails(int Id)  
  27.         {  
  28.             throw new NotImplementedException();  
  29.         }  
  30.   
  31.         public void UpdateCustomers(int ID)  
  32.         {  
  33.             throw new NotImplementedException();  
  34.         }  
  35.     }  
  36. }  
Client Code

  1. class Program  
  2.     {  
  3.           
  4.         static void Main(string[] args)  
  5.         {  
  6.             int CallCount;  
  7.             OrderService.OrderServiceClient orderService = new OrderServiceClient();  
  8.             CallCount = orderService.GetCallCount();  
  9.             Console.WriteLine(CallCount);  
  10.             CallCount = orderService.GetCallCount();  
  11.             Console.WriteLine(CallCount);  
  12.             CallCount = orderService.GetCallCount();  
  13.             Console.WriteLine(CallCount);  
  14.   
  15.             Console.ReadLine();  
  16.         }  
  17.     }  
Output




The client has called the method 3 times giving 1 as the output every time from the same instance of the service but it will consider it as a new call although it is being called.

Scenario: When to use per call is very important to understand. Suppose there is the requirement to build a scalable application and you don't need state between requests then per call would be the good choice because the per call mode is single-threaded and the instance would be destroyed after each call.

PerSession Mode: A new Instance Context, meaning service object, is created for each new client session and maintained for the lifetime of that session.

To make a service behave like a per session service, the service with the service behavior needs to be decorated with the instanceContextmode and that should be selected as perSession.
  1. [ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)]  
Sample Code: Per Session Sample code with service, client and configuration.

Service Code
  1. IOrderService  
  2.   
  3. namespace CustomerOrderService  
  4. {    
  5.     [ServiceContract]  
  6.     public interface IOrderService  
  7.     {  
  8.         [OperationContract]  
  9.         int GetCallCount();  
  10.           
  11.         [OperationContract]  
  12.         Customer GetCusomersDetails(int ID);  
  13.   
  14.         [OperationContract]  
  15.         void UpdateCustomers(int ID);  
  16.   
  17.         [OperationContract]  
  18.         void AddCustomers(Customer cust);  
  19.   
  20.     }      
  21. }  
Order Service

  1. namespace CustomerOrderService  
  2. {  
  3.     [ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)]  
  4.     
  5.   public class OrderService : IOrderService  
  6.     {  
  7.         Customer cust = null;  
  8.         private int _callCount;                              Instance Context Mode        
  9.         public int GetCallCount()  
  10.         {  
  11.             _callCount=_callCount+1;  
  12.             return _callCount;  
  13.         }  
  14.   
  15.        public Customer GetCusomersDetails()  
  16.         {  
  17.              throw new NotImplementedException();  
  18.   
  19.          }  
  20.   
  21.         public void AddCustomers(Customer cust)  
  22.         {  
  23.             throw new NotImplementedException();  
  24.         }  
  25.   
  26.         public Customer GetCusomersDetails(int Id)  
  27.         {  
  28.             throw new NotImplementedException();  
  29.         }  
  30.   
  31.         public void UpdateCustomers(int ID)  
  32.         {  
  33.             throw new NotImplementedException();  
  34.         }  
  35.     }  
  36. }  
Client Code

  1. class Program  
  2.     {  
  3.           
  4.         static void Main(string[] args)  
  5.         {  
  6.             int CallCount;  
  7.             OrderService.OrderServiceClient orderService = new OrderServiceClient();  
  8.             CallCount = orderService.GetCallCount();  
  9.             Console.WriteLine(CallCount);  
  10.             CallCount = orderService.GetCallCount();  
  11.             Console.WriteLine(CallCount);  
  12.             CallCount = orderService.GetCallCount();  
  13.             Console.WriteLine(CallCount);  
  14.   
  15.             Console.ReadLine();  
  16.         }  
  17.     }  
Output




The method is called 3 times and it is incremented by 1 every time, meaning it will be remembering the value after each call and treating it as a call from the same client and the Instance Context mode is set to be per session.

Note: BasicHttpBinding doesn't support sessions.

If the binding in a WCF service is set to basichttpbinding then per session mode will not work and the service will be considered to be per call.

Scenario: Whenever there is a need to maintain state between WCF calls this would be the best choice.

Single: a single instance will be created for the service object that will take care of all the requests coming from the same client or different ones, meaning that there is a need for one global instance for all the WCF clients. In this mode, the state is maintained between the various requests from the same client or from different clients also.
  1. [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]   
Sample Code

  1. namespace TestWin  
  2. {  
  3.     public partial class Form1 : Form  
  4.     {  
  5.         orderService.OrderServiceClient order = null;  
  6.         public Form1()  
  7.         {  
  8.             InitializeComponent();  
  9.             order = new orderService.OrderServiceClient();  
  10.         }  
  11.   
  12.         private void button1_Click(object sender, EventArgs e)  
  13.         {  
  14.             int count=order.GetCallCount();  
  15.             MessageBox.Show("Count is : " + count);  
  16.   
  17.         }  
  18.     }  
  19. }  

I have created two instances of a Windows app exe and by clicking on the button a single instance is available to handle the request and the count is being increased after clicking either of the exe buttons.

Output



Scenario: When global data must be shared across your WCF services and concurrency is a major issue then a single thread is available.

Conclusion

The WCF Framework has three modes available for different scenarios and you need to understand and use them in WCF to handle the client request. It is very important to understand the concept and use it in your application that helps you to architect applications with minimal issues of scalability and memory issues.

The next article will cover sessions and concurrency modes. It will be out soon.

Happy coding and keep learning and sharing!

References: https://msdn.microsoft.com/en-us/library/ms733040.aspx