Professional Documents
Culture Documents
Background
We have already seen how we can configure a WCF service instance as per our application needs
(A Beginner's Tutorial for Understanding WCF Instance Management [^]). Now in case we have
configured our WCF service to work in a stateful mode by setting the
InstanceContextMode
to PerSession, one more question arises. The question is how can we configure the service in
such a way that a particular order of operations in enforced on this stateful WCF service.
Why is this order important? The order is important because if our service is maintaining state for
every client then perhaps we need to do some initialization of resource acquisitions whenever the
instance is being created. The other functions of the service will then use these resources to
perform their operations. We would also want to ensure the that our resource cleanup is done
whenever a particular function is called (perhaps the last function in the sequence of functions).
Now we can very well define a convention that the clients should call some function first and
then call the other functions of the service so that the initial function will take care of all
initialization and the final function will take care of resource cleanup. But what if any client call
some intermediate function without calling the initialization function or after calling the cleanup
function? This could create some possible inconsistent behavior. WCF provide us a way to
enforce this convention and make sure that if any client calls any function without calling the
initialization function or after calling the cleanup function then the client call will fail.
before looking at the sequence specific configuration, let us understand a very important
property called SessionMode. The SessionMode property goes as part of
the ServiceContract attribute and it specifies how the service will implement
sessions. SessionMode can be set to three possible values:
1. Allowed
2. NotAllowed
3. Required
Allowed specifies that the service will allow the sessions if the sessions are supported by the
protocol being used i.e. binding and the InstanceContextMode is specified as PerSession.
NotAllowed specifies that the service will not allow the sessions even if the sessions are
supported by the binding and/or the InstanceContextMode is specified as PerSession.
Required option specifies that the service will support sessions and the underlying
binding/protocol should be chosen MUST support sessions.
As we have discussed above, if we need to enforce the order of operations in a WCF service, WCF
provides a way to mark a particular function as the function that should be the first function to be
called to initiate the instance creation process. This can be done by setting
the IsInitiating property of the OperationContract to true.
Similarly, to mark a function as the final function in a sequence of operations, we need to set
the IsTerminating property of the OperationContract to true.
The IsInitiating property for this function should be set to false.
Let us create a simple service with three operations. There will be one function(Function1) that
will initiate the instance creation, one function(Function3) that will terminate the instance. There
will be one more function that could only be called only when Function1 has been called
and Function3 has not yet been called. Calling this function otherwise would lead to an
exception.
[ServiceContract(SessionMode=SessionMode.Required)]
public interface ISampleService
{
// This function will INITIATE the session
[OperationContract(IsInitiating=true)]
string Function1();
// This function will work only if session has been INITIATED and not yet TERMINATED
[OperationContract(IsInitiating = false)]
string Function2();
[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)]
public class SampleService : ISampleService
{
public string Function1()
{
return "This function will INITIATE the session";
}
Creating a Host
Now since the ServiceContract has the SessionMode property set to Required, we will have
to choose the binding that supports sessions. So let us self host this service in a console
application that will expose the service via TCP. Since netTcpBinding supports sessions,
hosting this service using this binding will supports sessions.
Address: net.tcp://localhost/TestService
Binding: netTcpBinding
Contract: SampleServiceNamespace.SampleService
Console.ReadLine();
host.Close();
}
}
We can run the host to access our test service. Running the host will look like:
Note: Please refer to the app.config file of the host application to see the full configuration.
We will now create a simple test client that will call the WCF service functions. First let us try to
call the Function2 directly. Now since the Function1 is marked as IsInitiating=true,
direct call to
Function2
Now let us try the valid sequence of operations. We will call Function1(which is marked
as IsInitiating=true) then we will call Function2(which is supposed to be called
after Function1 and before Function3) and finally we will call Function 3(which is marked
as IsTerminating=false.
And now finally, let us try to call Function2 after call to Function3 has been completed. Since
Function3
has been marked as IsTerminating=true, call to Function2 after this will result in exception.
And thus by setting the IsInitating and IsTerminating property we have enforced as
sequence of operations in our WCF service.
WCF also provides a option for marking the service as Durable service. A durable service is a
service that persist the information of client sessions in some permanent stores like databases so
that even in case of service class instance goes off, it could regain the state information once a
new instance for the same client comes up. This is very useful when we need a stateful service
running for a long time.
A service can be marked as DurableService to make it a durable service. The functions should
also be marked as DurableOperation to make it a durable operation.
The DurableOperation supports the similar kind of properties to maintain order of operations.
For a durable operation, setting the CanCreateInstance to true will make the operation as the
first operation in the sequence and setting the CompleteInstance to true will make the
operation as terminating operation in in sequence.
Note: This is a very high level overview of durable services. Durable service creation requires
some more configuration to be done at service end.
Point of interest
In this article we saw how we can enforce an order/sequence of operations in a stateful WCF
service. This has been written from a beginner's perspective(but some knowledge of WCF service
and instance modes is required). I hope this has been informative.