Use of the Instance Context Mode in Windows Communication Foundation (WCF)

Introduction

This article illustrates the use of the InstanceContextMode property used in the ServiceBehaviour attribute and how it can be so handy in the latest communication technology Windows Communication Foundation (WCF), introduced by Microsoft as a part of the .NET framework SDK 3.0 and later versions.

I will be creating a demo application which will make use of the various instance context modes available in WCF, along with the explanation.

Why WCF?

I thought of providing a little information about why Windows Communication Foundation (WCF) is required in the .NET framework when there are already communication technologies like web services, enterprise services and remoting. WCF is introduced by Microsoft to achieve a Single Unified API for.NET services, so that in the future if any one speaks about service communication in .NET it would be only Windows Communication Foundation (WCF). Even though web service has proved to be stable it has a lot of limitations like statelessness and it also uses heavy soap to communicate so it is relatively slow. If you take remoting into consideration it can be consumed only by a .NET client and it could either be stateless or can only afford a singleton state.

When you consider WCF, it has a lot of flexibility which would allow you to configure the WCF application as per your needs. It can use many multiple message formats like text, Soap, Binary, REST and MTOM and different bindings like basicHttpBinding, wsHttpBinding, netTcpBinding and dualHttpBindings.

WCF can also maintain session based instances, singleton and also be stateless. This is achieved using the InstanceContextMode property, which we will be discussing in this article using a demo application.

Three Instance Context Modes

As I have mentioned ealiern, InstanceContextMode is nothing but a property which is available in the System.ServiceModel. This library is the one which encloses almost all the important WCF members. InstanceContextMode property is mainly used in the ServiceBehaviour attribute in order to mention what kind of state maintenance your WCF application should provide. The ServiceBehaviour attribute is designed at decorating the implementation classes in WCF.

There is also an enumerator available in the Sytem.ServiceModel library named as InstanceContextMode and it can be used in order to set the property InstanceContextMode.

There are three instance context modes available. I've listed them below:

  1. PerCall

    When you provide the instance context mode property as PerCall, it is like instructing your implementation class that state doesn't have to be maintained, so all the calls would become stateless. Below is the sample C# code showing how the property has to be set.

      [ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCall)]
    

    Since it is not going to maintain any states, you can use the basicHttpBinding for your WCF application.

  2. Single

    When you provide the instance context mode property as Single, it is like instructing your WCF implementation class to maintain a singleton state. What I meant by saying singleton would be clear for the readers who have exposure to the singleton design pattern in C# programming. A singleton class is a class for which at any point of time only one instance can be created and the same instance will be reused on subsequent requests."

    Below is the sample C# code showing how the property has to be set.

      [ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]
    

    Since it is going to maintain a single instance state, you cannot use the basicHttpBinding, but you can use any of the other bindings like wsHttpBinding.

  3. PerSession

    When you provide the instance context mode property as PerSession, it is like instructing your implementation class state that it has to be maintained based on client sessions. This is one major advantage of using WCF which offers session based state maintenance which was never previously offered by any of Microsoft's communication technologies like Remoting or Web Services.

    Below is the sample C# code showing how the property has to be set.

      [ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)]
    

    No surprise that this also doesn't work with basicHttpBinding, but works with all the other available bindings.

Now let us move onto creating the Demo Application. Let's create a sample Banking Application which will explain the Instance Context Modes pretty noticeably.

Banking Service Demo Application

Create Blank Solution

In the demo application we would be creating all the projects, including the client application in the same solution. So as a first step let us create a blank solution to which we will be adding all the projects to and name it as InstanceContextModeDemoSolution.

Create Contract Project

In WCF it should always be imbibed by the developers that the contract part should always be created as a separate project. This is because you have to provide the contract library to the client application, since it will be making use of it. If you mingle the contract and the implementation stuff in the same project, then you will end up providing the client with the implementation part as well.

Follow the below steps:

  1. Add a new project of type class library to the solution and name it as BankingService.Contract.
  2. Delete the default class1.cs file. Add an interface, name it as IBankingService and make it public
  3. Add the reference to System.ServiceModel library from GAC.

Below is the interface code

  using System;
  using System.ServiceModel;
  
  namespace BankingService.Contract
  {
      [ServiceContract]
      public interface IBankingService
      {
          [OperationContract]
          void DepositFund(int accountId, double amount);
          [OperationContract]
          void WithdrawFund(int accountId, double amount);
          [OperationContract]
          double GetBalance();
      }
  }

The interface has three method declarations DepositFund, WithdrawFund and GetBalance. These methods have to be implemented in the implementation class.

Create Implementation Project

Now let us create the implementation project which would contain the implementation classes for the contract which we have defined in the contracts project.

Follow the below steps:

  1. Create a project of type class library and name it BankingService.Implementation.
  2. Add the reference to the BankingService.Contract project and System.ServiceModel.
  3. Rename the default class as BankingService.
  4. Implement the interface IBankingService in the BankingService class.
  5. Create a class called Account.

Below is the Account class code

  namespace BankingLibrary
  {
      public class Account
      {   
          public int AccountId { get; set; }
          public string HolderName { get; set; }
          public double Balance { get; set; }
  
          public Account()
          {
              Console.WriteLine("Account Object Created");
          }
  
          public void Deposit(double amount)
          {   
              Balance += amount;
          }
  
          public void Withdraw(double amount)
          {
              Balance -= amount;
          }
  
          public double GetBalance()
          {
              return Balance;
          }
      }
  }

Below includes the code for the Implementation class BankingService, note that the ServiceBehaviour attribute is used and the InstanceContextMode property is set to InstanceContextMode.PerCall.

  namespace BankingService.Implementation
  {
      [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
      public class BankingService : IBankingService
      {
          Account _account;
  
          public BankingService()
          {
              _account = new Account();
          }
  
          #region IBankingService Members
  
          public void DepositFund(int accountId, double amount)
          {
              _account.Deposit(amount);
          }
  
          public void WithdrawFund(int accountId, double amount)
          {
              _account.Withdraw(amount);
          }
  
          public double GetBalance()
          {
              return _account.GetBalance();
          }
  
          #endregion
      }
  }

Create the Host Application

WCF applications always require a host application which will host the WCF service, so that it is available for the clients to consume. There are different ways of hosting the service but here we will use IIS hosting using a .svc file.

Follow the steps:

  1. Create a Web Application, choose the Location as HTTP instead of FileSystem.
  2. Provide the virtual directory as http://localhost/BankingService.
  3. Add the reference to the Contract and Implementation projects.
  4. Delete the default.aspx page. Add a text file and rename it to Service.svc
  5. Open Service.svc file and add the below tag
    <%@ ServiceHost Service="BankingService.Implementation.BankingService" %>
  6. Open the web.config file and add the below section under the configuration tag. Make sure you are using wsHttpBinding.

  <system.serviceModel>
  	<services>
  		<service behaviorConfiguration="BankingServiceBehaviour" name="BankingService.Implementation.BankingService">
  			<endpoint address="" binding="wsHttpBinding" contract="BankingService.Contract.IBankingService"></endpoint>
  		</service>
  	</services>
  	<behaviors>
  		<serviceBehaviors>
  			<behavior name="BankingServiceBehaviour">
  				<serviceMetadata httpGetEnabled="True" httpGetUrl=""/>
  			</behavior>
  		</serviceBehaviors>
  	</behaviors>
  </system.serviceModel>

Build your application and now it is hosted on IIS, ready for the clients to consume.

Use of the Instance Context Mode in Windows Communication Foundation (WCF)

Create Client Application

Now let us create a client Windows Presentation Foundation (WPF) application and consume the BankingService WCF application.

Follow the steps:

  1. Create a new project of type WPF application and name it as WpfBankingClient
  2. Rename the window to BankingWindow.xaml and also update the App.Xaml file with the new window name.
  3. Add references to System.ServiceModel and BankingService.Contract.
  4. There are two ways of consuming a WCF application, by using WSDL or using the ChannelFactory class. Here we will go with the ChannelFactory class.
  5. Below is the XAML code for the window
  6.   <Window x:Class="BankingClient.Window1"
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          Title="Banking Window" Height="300" Width="300">
          <Grid>
              <Label Margin="25,59,0,0" Name="label1" Height="28" HorizontalAlignment="Left" VerticalAlignment="Top" Width="65">AccId:</Label>
              <Label Height="28" HorizontalAlignment="Left" Margin="25,93,0,0" Name="label2" VerticalAlignment="Top" Width="65">Amount:</Label>
              <Button Margin="96,127,107,112" Name="Deposit" Click="Deposit_Click">Deposit</Button>
              <TextBox Height="23" Margin="96,59,62,0" Name="textBox1" VerticalAlignment="Top" />
              <TextBox Height="23" Margin="96,98,62,0" Name="textBox2" VerticalAlignment="Top" />
              <Button HorizontalAlignment="Right" Margin="0,127,26,112" Name="Withdraw" Width="75" Click="Withdraw_Click">Withdraw</Button>
              <Label Height="28" HorizontalAlignment="Left" Margin="25,0,0,65" Name="label3" VerticalAlignment="Bottom" Width="65">Balance:</Label>
              <Label Height="28" Margin="96,0,117,65" Name="BalanceValueLabel" VerticalAlignment="Bottom"></Label>
          </Grid>
      </Window>
    

  7. Add the below entry to the App.config file.

      <system.serviceModel>
      		<client>
      			<endpoint name="BankingClientEndPoint" address="net.tcp://localhost:9095/BankingService" binding="netTcpBinding" contract="BankingService.Contract.IBankingService"></endpoint>
      		</client>
      </system.serviceModel>
    

  8. Below is the code for BankingWindow.xaml.cs file

      public partial class BankingWindow : Window
      {
              IBankingService bankingService = null;
              public BankingWindow()
              {
                  InitializeComponent();
      
                  ChannelFactory<IBankingService> channelFactory = new ChannelFactory<IBankingService>("BankingClientEndPoint");
                  bankingService = channelFactory.CreateChannel();
              }
      
              private void Deposit_Click(object sender, RoutedEventArgs e)
              {
                  bankingService.DepositFund(Convert.ToInt32(textBox1.Text), Convert.ToDouble(textBox2.Text));
                  BalanceValueLabel.Content = bankingService.GetBalance();
              }
      
              private void Withdraw_Click(object sender, RoutedEventArgs e)
              {
                  bankingService.WithdrawFund(Convert.ToInt32(textBox1.Text), Convert.ToDouble(textBox2.Text));
                  BalanceValueLabel.Content = bankingService.GetBalance();
              }
          }
      }
    

Now we are ready to run the application.

PerCall Mode behavior

Remember that we have set the InstanceContextMode to PerCall earlier in the BankingService class in the BankingService.Implementation project.

Follow the below steps to check the behavior:

  1. Run the WpfBankingClient application.
  2. Enter AccountId as 1 and amount as 1000
  3. Click on deposit.

Our code calls the DepositFund method and adds 1000 to the balance and also makes another call to get the balance which returns 0. This is because a new instance of account is created every time since the InstanceContextMode is set to PerCall and it proves that our WCF application is stateless.

Fig 1.0 is the screenshot of the BankingWindow consuming WCF Server with InstanceContextMode set to InstanceContextMode.PerCall.

[banking1.jpg]
Fig 1.0

Single Mode Behavior

Now change the InstanceContextMode property to Single in the BankingService class in BankingService.Implementation project.

Follow the below steps to check the behavior:

  1. Run two instances of the BankingWindow.
  2. Enter AccountId as 1 and amount as 1000 in the first window.
  3. Click on Deposit.
  4. Enter AccountId as 2 and amount as 2000 in the second window.
  5. Click on Deposit.

Now you see the balance in the first window is 1000 and in the second window it is 3000 even though only 2000 is deposited. This is because the same instance is used by the WCF service, no matter how many different clients call the service and we have set the InstanceContextMode as Single. It proves that our WCF application is a Singleton now.

Fig 1.1 is the screenshot of the BankingWindow consuming WCF Server with InstanceContextMode set to InstanceContextMode.Single.

[consume2.jpg]
Fig 1.1

PerSession Mode Behavior

Now change the InstanceContextMode property to Session in the BankingService class in the BankingService.Implementation project.

Follow the below steps to check the behavior.

  1. Run two instances of the BankingWindow.
  2. Enter AccountId as 1 and amount as 1000 in the first window.
  3. Click on Deposit.
  4. Enter AccountId as 2 and amount as 2000 in the second window.
  5. Click on Deposit.

Now see the balance in the first window is 1000 and in the second window it is 2000, this is because the instance is maintained based on the client sessions. It proves that our WCF application creates new instances and maintains separately for each and every client instance.

Fig 1.2 is the screenshot of the BankingWindow consuming WCF Server with InstanceContextMode set to InstanceContextMode.PerSession

[banking3.jpg]
Fig 1.2

Conclusion

I hope this article provide a clear demonstration of how the state of the WCF service is maintained based on the session and how the InstanceContextMode property plays a role in achieving this. The PerSession state maintenance is a most important feature which makes WCF superior to other communication technologies (services) that are provided by Microsoft.

I have also attached the .zip file containing the demo application, which we developed.



About the Author

V.N.S Arun

I work for an MNC in Bangalore, India. I am fond of writing articles, posting answers in forums and submitting tips in dotnet. To contact me please feel free to make use of the "Send Email" option next to the display name.

Downloads

Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • The explosion in mobile devices and applications has generated a great deal of interest in APIs. Today's businesses are under increased pressure to make it easy to build apps, supply tools to help developers work more quickly, and deploy operational analytics so they can track users, developers, application performance, and more. Apigee Edge provides comprehensive API delivery tools and both operational and business-level analytics in an integrated platform. It is available as on-premise software or through …

  • Stories about devastating cyberattacks are plaguing the news. Why? The DNS protocol is easy to exploit. See your network the way hackers do—as an easy target. Learn how you can effectively secure your DNS infrastructure today.

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds