When I started learning WCF, First thing I learnt was “Service is just like another class”. Okay so if WCF is a class which instance of class will handle request from client? Confusing? May be! In this post let us explore WCF Instance Management.

In WCF, Instance Management is a technique to decide which service instance will serve a client request. It also decides when a client request will be served by a service instance. Instance Management is very important factor while designing service. Its affects

  • Scalability of Service
  • Performance of Service
  • Durability of Service
  • Transactions
  • Service Queues

Instance Management can be seen as set of techniques to decide which service instance will serve a client request and when.

There are three different kinds of Instance Management techniques.

  1. Per-Call Instance Management technique
  2. Per-Session Instance Management technique
  3. Singleton Instance Management technique

image

Before we go ahead into details of Instance management, we need to understand about BEHAVIORS in WCF. Using Behaviors any service side implementation details can be abstracted from the client. Since Instance management is service side behavior, so its implementation details will be abstracted from client using Service side Behaviour. Some points about BEHAVIORS are as follows,

  • Behavior is a local attribute of service that does not affect its communication patterns.
  • Client does not aware of the Behavior.
  • Service does not manifest Behavior in binding or metadata.
  • Practically Behaviors are WCF classes.
  • Behaviors get executed at the runtime.

There are three kinds of behaviors.

  1. Service Behaviors
  2. EndPoint Behaviors
  3. Operation Behaviors

image

Service Behaviors directly get apply to service implementation class. It affects all the EndPoints and it is used to configure Service Instance Mode. Operation Behaviors is used to configure operation behavior and it affects only implementation of a particular operation. It could apply only to method that implements contract operation .It is not applied to the contract definition itself.

Now let us go back to Instance Management. We use Service Behavior to configure Instance Mode on a WCF Service. InstanceConextMode is an enum in System.ServiceModel which is used to configure Instance mode of a service.

Enum InstanceContextMode is defined as below in System.ServiceModel.

image

As we saw earlier that there are three Instance Mode techniques. These three techniques work as follows,

image

Per-Call Instance mode creates new instance for each request from client. When client request is served instance is disposed. To demonstrate Per-Call instance technique define a service as below,


    [ServiceContract]
    public interface IService1
    {

        [OperationContract]
        int counter();     

    }  

To expose service as Per-Call Instance mode, Service behavior need to be configured as below,

image

You just need to set InstanceContextMode as InstanceContectMode.PerCall to enable service as Per-Call Service. To demonstrate Per-Call we have implemented service as below,

 


[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCall)]
    public class Service1 : IService1,IDisposable
    {
        static int _counter = 0;
        public Service1()
        {
            _counter = _counter + 1;
        }
       public int counter()
        {
            return _counter;

        }

        public void Dispose()
       {
           _counter = _counter - 1;

       }

    }

In above service implementation, we have taken a static counter. To demonstrate Per-Call instance mode,

  • Incrementing value of counter in service constructor. As definition of Per-Call Instance mode on each client request service instance will get created. So for each request counter value will be increased by one in the constructor.
  • When service is served, service instance will be disposed. In disposed method we are decrementing counter by one.
  • Service is returning counter value.

As you notice we are implanting IDispose to write our own code in Dispose method. To configure service in Per-Call Instance mode, service behavior is configured as InstanceContextMode.PerCall .

To test Per-Call Instance mode configured service, I have created console application client.

 


static void Main(string[] args)
        {
            Service1Client proxy = new Service1Client();
            var result = proxy.counter();
            Console.WriteLine(result);
            Console.ReadKey(true);
            Service1Client proxy1 = new Service1Client();
            var result1 = proxy1.counter();
            Console.WriteLine(result1);
            Console.ReadKey(true);
        }

Run application and you will get output as

clip_image002

As you see we are getting 1 as output on each client request because for each client request service is creating a new instance and disposing instance once call is served. We are increasing value of counter in constructor and then decreasing it in dispose method, so across service call value of counter at service remains same.

Ideally value of counter should increase in each request from client and you should get output something like below,

clip_image004

We are not getting above output because service is configured to work in Per-Call Instance Mode. To get default service as behavior as above remove Instance Mode configured as Per-Call in service configuration.

Per-Session Instance mode creates separate Service instance for separate proxy at the client. So if a Service is configured as Per-Session or session-full service then for each proxy at client new service instance gets created. In Per-Session Instance mode is client proxy has a new service instance. In Per-Session Instance mode, WCF maintains a logical session between client and service. Service instance remains in memory throughout the session.

In Per-Session Instance mode, when client creates new proxy either of same EndPoint or different EndPoint, Service creates new instance to serve new proxy.

To configure service to work in Per-Session mode, there are three facets we need to take care of.

  1. Configure behavior of Service to work in Per-Session Instance mode
  2. Create EndPoint using Bindings which support sessions. For example basicHttpBinding may not support Session-full service.
  3. In contract of service we need to tell client that this service will work in session-full mode.

image

Let us rewrite service used in Per-Call example in Per-Session Instance Mode.

image

Behavior facet of session-full service is configured by configuring service Instance mode as InstanceContextMode.PerSession, WCF keeps Service instance alive for throughout the session. The session terminates when client closes the proxy. On closing proxy notifies the service that session has been closed and service calls dispose on service instance.

Contract facet of session-full service is configured by configuring other attribute of service behavior SessionMode. SessionMode can be set to either of the following three values,

  1. Allowed
  2. NotAllowed
  3. Required

image

By default SessionMode is set to Allowed and it is exposed to client in Service metadata.

When SessionMode is set to SessionMode.Allowed then transport sessions are allowed but not enforced. The behavior of service will depend on other two facets i.e. behavior configuration and binding of the service.

Some of the points to keep in mind about allowed SessionMode are as follows,

  • If Service is configured as PerCall, it will behave as Per Call Instance Mode. Whereas, if service is configured as PerSession, it will behave as PerSession but if binding is not supporting session, it will behave as PerCall instance mode.
  • If service is configured as PerSession and binding is basicHttpBinding, which is a connection less binding then service cannot use Transport level session and it will behave as Per Call configured service.
  • If binding is WSHttpBinding and service is configured as session full service. It will act as Per-Call instance management service, if security and reliability of message is not enabled.

When SessionMode is set to SessionMode.Required then transport session are enforced. If service is configured as SessionMode.Required with a service EndPoint in which binding does not maintain a Transport level session a run time error will encountered at executing service.

If service is configured as PerSession and contract is configured as SessionMode.Required then service will act as session-full service. However if binding is not supporting session, it will throw run time error while executing the service.Take an example service is configured as PerSession with Contract as SessionMode.Required and binding is basicHttpBinding, which is a connectionless binding then service, cannot use Transport level session and it will throw error while service is loading.

When SessionMode is set to SessionMode.NowAllowed then transport session are not allowed. Regardless of service configuration, if service SessionMode is set to value NotAllowed then service will behave as Per-Call service. We need to cautious before making SessionMode as NotAllowed. For example TCP and IPC protocols maintain a session at Transport level, so if End Point is configured as NetTcpBinding or NetNamePipeBinding and contract as SessionMode.NowAllowed , WCF throw an runtime error while loading the service.

Let us see InstanceContextMode.PerSession is in action. I have created a service with SessionMode set to value Required.

 


[ServiceContract(SessionMode=SessionMode.Required)]
    public interface IService1
    {
        [OperationContract]
        int counter();    

    }  

 

Next we implement the service in exactly the same way implemented for InstanceContextMode.PerCall. However in this service is configured in InstanceContextMode.PerSession mode.

 

[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)]
    public class Service1 : IService1
    {
        static int _counter = 0;
        public Service1()
        {
            _counter = _counter + 1;
        }
       public int counter()
        {
            return _counter;

        }

        public void Dispose()
       {
           _counter = _counter - 1;

       }

    }

 

In above service implementation, we have taken a static counter. To demonstrate Per-Session instance mode,

  • Incrementing value of counter in service constructor. As definition of Per-Session Instance mode for each client proxy, new service instance will get created. So for each proxy counter value will be increased by one in the constructor.
  • When proxy is closed service instance will be disposed. In disposed method we are decrementing counter by one.
  • Service is returning counter value.

As you notice we are implanting IDispose to write our own code in Dispose method. To configure service in Per-Session Instance mode, service behavior is configured as InstanceContextMode.PerSession .

To test Per-Session Instance mode configured service, I have created console application client.

 


Service1Client proxy1 = new Service1Client();
            var result = proxy1.counter();
            Console.WriteLine("First Call from Proxy 1 : " + result);
            var result1 = proxy1.counter();
            Console.WriteLine("Second  Call from Proxy 1 : " + result1);
            Service1Client proxy2 = new Service1Client();
            var result2 = proxy2.counter();
            Console.WriteLine("First Call from Proxy2 :" + result2);
            proxy1.Close();
            proxy2.Close();
            Console.ReadKey(true);

Run application and you will get output as,

clip_image002

We can infer from output that for first proxy same service instance is being used across the calls. So for both request service is returning same value of counter. Whereas for second proxy value of counter has been increased and because a new service instance got created.

Third instance management technique in Single or Singleton Instance Management. When a Service is configured as a Singleton, all clients connect to the same shared Service Instance regardless of EndPoint. In Single Instance management, there is only one instance of service gets created and serve to all clients.

In Single Instance mode service Instance created only once. It created when the service host is created and lives forever. It got disposed only when host shuts down. In this instance mode client does not maintain any logical session.

Single instance mode does not restrict client to consume a contract with session enabled. Suppose client is consuming a contract, which is having session then during the service call the Singleton service instance will have the same Session Id as of the client. When client will close the proxy that will terminate only the Transport session not the Singleton service instance. Whereas, if the client is consuming a contract, which does not have session. That client will also get connected to the same shared singleton service instance.

There are some disadvantages of using Single instance mode. Like it is having scalability problem. All requests to service will run on different worker thread, so it will cause synchronization problem. Only one client could have access to singleton service instance at a time. It will decrease throughput of the service. Responsiveness is very low. Single instance mode should only be used, when no other options are available. For instance Global Log Book, Single Communication Port etc.

Let us go ahead and implement Single instance mode. To demonstrate Single instance mode, I have created two service contract. First service contract is configured with SessionMode.Required and second service contract is configured with SessionMode.Allowed.

 


[ServiceContract(SessionMode=SessionMode.Required)]
    public interface IService1
    {
        [OperationContract]
        int CounterSessionRequired();        

    }

    [ServiceContract(SessionMode = SessionMode.NotAllowed)]
    public interface IService2
    {

        [OperationContract]
        int CounterSessionNotAllowed();

    }

Next we have implemented service as below. Same implantation of PerCall or PerSession instance mode is being used here to demonstrate Single instance mode

 


    [ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]
    public class Service1 : IService1,IService2
    {
        static int _counter = 0;
        public int CounterSessionRequired()
        {
            _counter++;
            return _counter;

        }

        public int CounterSessionNotAllowed()
        {
            _counter++;
            return _counter;

        }

    }

In above service implementation, we have taken a static counter. To demonstrate Single instance mode. We are increasing value of counter in operation contracts of different service contracts. We are going to expose these two service contract on different addresses. This can be configured as below,

 


<services>
      <service name="MessagePatternDemo.Service1">
        <!-- Service Endpoints -->
        <endpoint address="RequiredService"
                  binding="wsHttpBinding"
                  contract="MessagePatternDemo.IService1">
        </endpoint>

        <endpoint address="AllowedService"
                  binding="wsHttpBinding"
                  contract="MessagePatternDemo.IService2">

        </endpoint>

        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>
    </services>

Now at the client side both services are consumed as below,

 


Service1Client proxy1 = new Service1Client();
            var result = proxy1.CounterSessionRequired();
            Console.WriteLine("First Call from Proxy 1 : " + result);
            Service2Client proxy2 = new Service2Client();
            var result2 = proxy2.CounterSessionNotAllowed();
            Console.WriteLine("First Call from Proxy2 :" + result2);
            proxy1.Close();
            proxy2.Close();
            Console.ReadKey(true);

We are calling both services with different proxy but at the service side single service instance is getting created. As an output each time you will get increased value of counter from the service. So we can conclude that single instance of service is being used by all proxies at clients.

In this post, we learn about Instance Modes on WCF Services. There are three types and we need to choose them wisely on basis of requirements. While choosing instance mode make sure that you have configured service with proper binding. For example don’t do mistake of creating Session-full service with basicHttpBinding. I hope this post is useful to you. Thanks for reading.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s