Section 4.5. Demarcating Operations


4.5. Demarcating Operations

Sometimes, a sessionful contract has an implied order to operation invocations. Some operations cannot be called first, while other operations must be called last. For example, consider this contract used to manage customer orders:

 [ServiceContract(SessionMode = SessionMode.Required)] interface IOrderManager {    [OperationContract]    void SetCustomerId(int customerId);    [OperationContract]    void AddItem(int itemId);    [OperationContract]    decimal GetTotal( );    [OperationContract]    bool ProcessOrders( ); } 

The contract has the following constraints: the client must provide the customer ID as the first operation in the session, or else no other operations can take place; items may be added, and the total calculated, in any order, and as often as the client wishes; processing the order terminates the session, and therefore must come last.

WCF allows contract designers to designate contract operations as operations that can or cannot start or terminate the session using the IsInitiating and IsTerminating properties of the OperationContract attribute:

 [AttributeUsage(AttributeTargets.Method)] public sealed class OperationContractAttribute : Attribute {    public bool IsInitiating    {get;set;}    public bool IsTerminating    {get;set;}    //More members } 

Using these properties may demarcate the boundary of the session; hence I call this technique demarcating operations. During the service load time (or the proxy use time on the client side), if these properties are set to their nondefault values, WCF verifies that the demarcating operations are part of a contract that mandates sessions (SessionMode is set to SessionMode.Required), and will throw an InvalidOperationException otherwise. Both a sessionful service and a singleton can implement a contract that uses demarcating operations to manage their client sessions.

The default values of these properties are IsInitiating set to true and IsTerminating set to false. Consequently these two definitions are equivalent:

 [ServiceContract(SessionMode = SessionMode.Required)] interface IMyContract {    [OperationContract]    void MyMethod( ); } [ServiceContract(SessionMode = SessionMode.Required)] interface IMyContract {    [OperationContract(IsInitiating = true,IsTerminating = false)]    void MyMethod( ); } 

As you can see, you can set both properties on the same method. In addition, operations do not demarcate the session boundary by defaultoperations can be called first, last, or in between any other operation in the session. Using nondefault values enables you to dictate that a method is not called first, or that it is called last, or both:

 [ServiceContract(SessionMode = SessionMode.Required)] interface IMyContract {    [OperationContract]    void StartSession( );    [OperationContract(IsInitiating = false)]    void CannotStart( );    [OperationContract(IsTerminating = true)]    void EndSession( );    [OperationContract(IsInitiating = false,IsTerminating = true)]    void CannotStartCanEndSession( ); } 

Going back to the order management contract, you can use demarcating operations to enforce the interaction constraints:

 [ServiceContract(SessionMode = SessionMode.Required)] interface IOrderManager {    [OperationContract]    void SetCustomerId(int customerId);    [OperationContract(IsInitiating = false)]    void AddItem(int itemId);    [OperationContract(IsInitiating = false)]    decimal GetTotal( );    [OperationContract(IsInitiating = false,IsTerminating = true)]    bool ProcessOrders( ); } //Client code OrderManagerClient proxy = new OrderManagerClient( ); proxy.SetCustomerId(123); proxy.AddItem(4); proxy.AddItem(5); proxy.AddItem(6); proxy.ProcessOrders( ); proxy.Close( ); 

When IsInitiating is set to TRue (its default) it means the operation will start a new session if it is the first method called by the client, but that it will be part of the on-going session if another operation is called first. When IsInitiating is set to false, it means that the operation can never be called as the first operation by client in a new session, and that the method can only be part of an ongoing session.

When IsTerminating is set to false (its default), it means the session continues after the operation returns. When IsTerminating is set to true, it means the session terminates once the method returns, and WCF disposes of the service instance asynchronously. The client will not be able to issue additional calls on the proxy. Note that the client should still close the proxy.

When you generate a proxy to a service that uses demarcating operations, the imported contract definition contains the property settings. In addition, WCF enforces the demarcation separately on the client and on the service side, so that you could actually employ them separately.





Programming WCF Services
Programming WCF Services
ISBN: 0596526997
EAN: 2147483647
Year: 2004
Pages: 148
Authors: Juval Lowy

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net