Do you know we can control the instance creation of WCF service class? Yes, in WCF we can control the WCF service instance unlike WebAPI.
In this article I will discuss different instance modes provided by the WCF framework. I will use the C# language for the examples in the post.
WCF Service Instance
- Determines when the host will new up a new instance of the service
- WebApi is based on HTTP which means it is stateless while WCF can be HTTP based but it knows how to manage the state at host .
- 3 modes of instantiation i.e PerCall, PerSession, Single
- Setting instance mode is done through inline code and not through config as changing it can lead to absurd results.
- It is set using the ServiceBehaviour attribute class and setting InstanceContextMode.
- PerSession mode is the default mode for the WCF services.
Lets discuss all the three modes of instancing with examples
PerCall Instancing
- For each call from the proxy(in any client) is serviced by a brand-new instance of the service.
- For every call the host creates a new instance and disposes it.
- This is the case even if the client proxy stays open.
- Most scaleable solution
- Nothing is left open in the memory
- Preferred method unless we need some state.
- Typical in and out SOA calls.
- Service cannot hold in memory state.
Lets see an example of per call instancing. I will use the service which I have created in one of my previous article about WCF service. I have used the netTcpBinding for all the examples in this article.
For demo purpose I have changed the code of the service class as shown below
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)] public class MyServiceImplementation : IMyService { public string Hello(PersonData person) { return "Hello " + person.FirstName + " My Hash Code is: " + GetHashCode(); } }
In the code above I am returning the HashCode of the class along with the message. And added the ServiceBehavior attribute for the service with instance context mode as PerCall. To add the ServiceBehaviour attribute we have to include a reference of System.ServiceModel assembly.
HashCode of the each instance of a class will be different. If the instances are same the hash code will be same.
In the client I will call the same method using the same instance of the proxy as shown below.
PersonData person = new PersonData() { FirstName = "Vikram" }; MyServiceProxy proxy = new MyServiceProxy(); Console.WriteLine(proxy.Hello(person)); Console.WriteLine(proxy.Hello(person)); Console.Read();
The output of the above code is shown in the below figure.
As seen in the above result. Fo reach call from the call, a new instance of the service is getting created.
PerSession Instancing
- Host will new up the service instance on the first call from proxy or when the proxy is opened using proxy.open().
- While the proxy is open all the call from this proxy are serviced by the same instance.
- Service can hold in-memory state
- Class – scoped variables can exist and maintain their state across multiple calls.
- If we need to update the state, we need locking. Please check this article about Thread synchronisation and locking mechanism in .NET
- When proxy is closed, service instance is disposed in which WCF makes a call to the service host to get rid of it.
- The life time of the service is equated to the life time of proxy.
- This is default on WCF as it most closely resembles the conventional object usage
- Transport session is must for this instancing to work
Following protocols support the PerSession WCF Service Instance.
- TCP Binding
- IPC Binding
- Ws-Http binding with reliability or security turned on.
- If it is simple httpBinding or WS-Http binding without reliability or security turned on it is down graded to Per-call instancing.
I have changed the code of the Client as following and changed the ServiceBehaviour attributes InstanceContextMode to PerSession
PersonData person = new PersonData() { FirstName = "Vikram" }; MyServiceProxy proxy = new MyServiceProxy(); Console.WriteLine(proxy.Hello(person)); Console.WriteLine(proxy.Hello(person)); MyServiceProxy proxy1 = new MyServiceProxy(); Console.WriteLine(proxy1.Hello(person));
In the above code I have created two instances of the proxy. Lets see the output.
As we can see in the figure. First two calls are made using the same instance of the proxy, that is why they are returning the same hast code. The next call is made using the different instance, it returns a new hash code confirming our belief about the per session instancing.
Single Instancing
- Host news up service instance when opened up.
- All calls by the service proxy are served by the single instance.
- Locking needs to be taken care of as it is a singleton instance.
- The life time of the service is not equated to the client it is equated to the host as unless and until host is not closed instance is not disposed.
I have kept the client code same as from the example of the PerSession and changed the InstanceContextMode = InstanceContextMode.Single for service.
Check the below figure for the result.
As we can see the hash code is same for all the calls. Signifying that the same WCF Service Instance is serving the requests. Even of we call the service instance from different clients we will get the same instance.
Conclusion:
In this article I have discussed the WCF Service Instance and how it can be controlled using the ServiceBehaviour attribute class. I have discussed all the three ways of creating the service instance i.e. PerCall, PerSession and Single with examples.
Leave a Reply