1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Behaviors in WCF

Discussion in 'ASP.NET' started by MinalS, Nov 25, 2014.

  1. MinalS

    MinalS New Member

    Joined:
    Jul 8, 2014
    Messages:
    138
    Likes Received:
    30
    Trophy Points:
    0
    The behaviors can be distinguished into three types Service Behaviors, Endpoint Behaviors, and Operation Behavior. The Service Behaviors are executed at the service level and provide access to the endpoints. They are useful in auditing, authorization, instancing and transactions. The Endpoint Behavior is limited to the service endpoint. The messages transferring through the services are monitored by the endpoint. Operation Behavior is specified at the operation level. They are used for transaction flow, parameter handling, and manipulating serialization.

    The behaviors are used on data before it is transferred or received. The functions provided at the client side are as mentioned below:
    1. Parameter Inspection: It is used to check and modify the data in the .NET representation. Later, the data is converted into XML format.
    2. Message Formatting: It is used to check and modify the data during the conversion between the .NET types and XML.
    3. Message Inspection: It is used to change data in XML format, before the conversion into .NET types.
    On the server side, the behavior can be used in following conditions.
    1. Operation Selection: It is used for inspecting the messages and decides which operation must be called.
    2. Operation Invocation: It is used for invoking the class method at the operation level.

    Concurrency and Instantiation in Service Behavior



    The concurrency term is used to count the number of tasks can be performed simultaneously. The execution time is defined as the time required completing the task. The Throughput is used to measure the tasks that are completed in a fixed time. It is used as a function of concurrency and execution time.

    User can increase the throughput in two different ways by decreasing the execution time and increasing the concurrency time. WCF contains two behaviors for managing the concurrency. They are InstanceContextMode and ConcurrencyMode.

    The InstanceContextMode is used to control instancing. It contains three parameter values.
    1. Single: One instance is used for handling the incoming requests. It is used for implementing singleton.
    2. PerCall: One instance of the service class is created for one incoming request.
    3. PerSession: It is used for creating one instance of the service class per client session.
    The ConcurrencyMode service behavior is used to control the concurrency of the thread in a service instance. User can set the behavior to any of the following values.
    1. Single: One thread can access the service class. The thread safety is ensured.
    2. Reentrant: Only one thread can access the service class, it can leave the class can start the execution later
    3. Multiple: Multiple threads can access the service class simultaneously.

    Implementing a Singleton



    There are certain requirements when user wants only a single instance of a service to be created. The tasks are processed in the first in first out order. For creating a single service in a single threaded application, the InstanceContextMode.Single and ConcurrencyMode.Single are added in the attribute. The InstanceContextMode.Single attribute indicates that only one instance is created. The ConcurrencyMode.Single is used to direct the WCF for executing a single instance at a time.

    The following code snippet demonstrates the singleton behavior.
    Code:
    [ ServiceContract ]
    public interface IService1
    {
        [ OperationContract ]
        double GetCost( string name );
    }
    
    [ ServiceBehavior ( InstanceContextMode=InstanceContextMode.Single, ConcurrencyMode=ConcurrencyMode.Single ) ]
    
    public class Service1:IService1
    {
        Service1()
    {
            Console.WriteLine(“{0}: New instance created”,System.DateTime.Now);
    }
    public double GetCost( string name )
    {
    Console.WriteLine(“{0}”:The GetCost method is called {1}”, System.DateTime.Now,Thread.CurrentThread.ManagedThreadId);
        Thread.Sleep(2000);
        return 20000;
    }
    }
    

    MultiThreading a Single Instance



    When user wants to create a single service instance to be shared by the current threads, InstanceContextMode.Single along with ConcurrencyMode.Multiple should be used. The multiple setting in the concurrency indicates that the WCF can execute an instance on multiple threads simultaneously.

    The following code demonstrates service using multithreading for a single thread instance.
    Code:
    [ ServiceContract ]
    public interface IService1
    {
        [ OperationContract ]
        double GetCost( string name );
    }
    
    [ ServiceBehavior ( InstanceContextMode=InstanceContextMode.Single, ConcurrencyMode=ConcurrencyMode.Multiple ) ]
    
    public class Service1:IService1
    {
        Service1()
    {
            Console.WriteLine(“{0}: New instance created”,System.DateTime.Now);
    }
    public double GetCost( string name )
    {
    Console.WriteLine(“{0}”:The GetCost method is called {1}”, System.DateTime.Now,Thread.CurrentThread.ManagedThreadId);
        Thread.Sleep(2000);
        return 20000;
    }
    }
    

    Session Level Instances



    In distributed applications, per state user is maintained through sessions. Similarly, in web applications it is easy to store per state user information in sessions. This concept is supported by the WCF. The InstanceContextMode.PerSession is used for creating an instance of a service for each session.

    For implementing the per session service instance, user must enable sessions at the contract level and at service level. At the contract level, the sessions are enabled through SessionMode behavior on the service contract. The parameters can be Allowed, NotAllowed, or Required. At the service level, the sessions are enabled using the InstanceContextMode behavior property as InstanceContextMode.PerSession. The parameters that can be used are PerCall or Single.PerCall. The PerCall is used to create a new service instance for every call and Single maintains one instance for all the callers.

    The following code snippet demonstrates the PerSession instancing.
    Code:
    [DataContract]
    
    class ProductData
    {
        
    [DataMember]
    public double cost;
    
    [DataMember]
    public int calls;
    }
    
    [ServiceContract ( SessionMode = SessionMode.Required ) ]
    public interface IService1
    {
        [ OperationContract ]
        double GetCost( string name );
    }
    
    [ ServiceBehavior ( InstanceContextMode=InstanceContextMode.PerSession, ConcurrencyMode=ConcurrencyMode.Multiple ) ]
    
    public class Service1:IService1
    {
    System.Object.lockThis = new System.Object ();
        private int no_calls = 0;
        Service1()
    {    
            Console.WriteLine(“{0}: New instance created”,System.DateTime.Now);
    }
    public ProductData GetCost( string name )
    {
        ProductData d= new ProductData();
    Console.WriteLine(“{0}”:The GetCost method is called {1}”, System.DateTime.Now,Thread.CurrentThread.ManagedThreadId)
    ;
    d.cost=100.50;
    lock(lockthis)
    {
        d.calls=++no_calls;
    }
        Thread.Sleep(2000);
        return (d);
    }
    }
    
    In the above code, The GetCost method is called synchronously. The counter no_calls is stored in the service session instance. The counter value is initialized to 0. If the InstanceContextMode is set to PerCall, every client would see the number of counts remaining for successive calls.

    Controlling the Number of Concurrent Sessions



    Using the InstancingMode as PerSession, the WCF application creates an instance for a session. It is used for connecting to the service. The maxConcurrentSessions behavior is used for controlling the number of connected sessions. If the maximum limit of an active client is reached, the next client can approach to the service. It is very helpful for controlling the number of users that are connected to the service.

    The following code is used for creating a service using InstanceContextMode.PerSession and ConcurrencyMode.Multiple.

    Code:
    [ ServiceContract ( SessionMode = SessionMode.Required ) ]
    public interface IService1
    {
        [ OperationContract ]
        double GetCost( string name );
    }
    
    [ ServiceBehavior ( InstanceContextMode=InstanceContextMode.PerSession, ConcurrencyMode=ConcurrencyMode.Multiple ) ]
    
    public class Service1:IService1
    {
        Service1()
    {
            Console.WriteLine(“{0}: New instance created”,System.DateTime.Now, OperationContext.Current.SessionId);
    }
    public double GetCost( string name )
    {
    Console.WriteLine(“{0}”:The GetCost method is called {1}”, System.DateTime.Now,Thread.CurrentThread.ManagedThreadId);
        Thread.Sleep(2000);
        return 20000;
    }
    }
    
    The app.config file for demonstrating the service is as shown below:
    Code:
    <? xml version=”1.0” encoding=”utf-8” ?>
    <configuration>
    
    <system.serviceModel>
    <services>
        <service name=”InfoWCF.IService1” behaviorConfiguration=”throttling” >
        <host>
            <baseAddresses>
            <add baseAddress=”http://localhost:8000/InfoWCF” />
            </baseAddresses>
        </host>
        <endpoint address=” “ binding=”wsHttpBinding” contract=”InfoWCF.Service1” />
        </service>
    </services>
    
    <behaviors>
        <serviceBehaviors>
        <behavior name=”throttling” >
        <serviceThrottling maxConcurrentSessions=”5” />
        </behavior>
        </serviceBehaviors>
    </behaviors>
    </system.serviceModel>
    
    </configuration>
    

    Exploring and publishing MetaData



    The Addresses, Bindings and Contract ( ABC ) are represented in the metadata. The information is known as service metadata. The following two steps are to be performed for using the metadata.
    1. The default export format WSDL is used to read and publish the information.
    2. It publishes the metadata using the MS – MetadataExchange protocol over any other supported transport protocols.
    The metadata is exposed through the through the Metadata Exchange endpoint. It is also known as MEX. It consists of an address, binding and contract. It consists of IMetaDataExchange interface and its contract. It is defined in the System.ServiceModel.Description namespace. The bindings available with the MEX are mexHttpBinding, mexHttpsBinding, mexNamedPipeBinding, and mexTcpBinding.
    The configuration for enabling metadata with the serviceMetadata is as shown below:
    Code:
    <? xml version=”1.0” encoding=”utf-8” ?>
    <configuration>
        <system.serviceModel>
        <services>
        <service name=”InfoWCF.Service1” behaviorConfiguration=”behavior1” >
        <host>
            <baseAddresses>
            <add baseAddress=”http://localhost:8080/InfoWCF” />
            </baseAddresses>
        </host>
        <endpoint address=” “ binding=”basicHttpBinding” contract=”InfoWCF.Service1” />
        <endpoint address=”mex” binding=”mexHttpBinding” contract=”IMetadataExchange” />
        </service>
        </services>
    
    <behaviors>
        <serviceBehaviors>
        <behavior name=”behavior1” >
            <serviceMetadata httpGetEnabled=”True” />
        </behavior>
        </serviceBehaviors>
    </behaviors>
    
    </system.serviceModel>
    </configuration>
    
    The Self hosted code for the metadata publishing is as shown below:
    Code:
    [ ServiceContract ]
    public interface IService1
    {
        [ OperationContract ]
        double GetCost ( string name );
    }
    
    public class Service1: IService1
    {
        public double GetCost ( string name )
        {
            return 1000.60;
        }
    }
    
    public class service
    {
        public static void Main ( string[] args )
        {
            ServiceHost sv1 = new ServiceHost ( typeof ( Service1 ) , 
            new Uri ( “http://localhost:8000/InfoWCF” ) );
            serviceHost.AddServiceEndPoint( typeof ( IService1 ), new BasicHttpBinding(), “ “ );
            ServiceMetadataBehavior behavior = new ServiceMetadataBehavior ();
            behavior.HttpGetEnabled = true;
            servicehost.Description.Behaviors.Add(behavior);
            servicehost.AddServiceEndpoint ( 
            typeof ( IMEtaDataExchange ) , MetadataExchangeBindings.CreateMexHttpBinding(), “mex” );
            sv1.Open();
            Console.WriteLine (“The service is ready”);
            Console.Read();
            sv1.Close();
        }
    }
    

    Operation Behavior (Implementing Transactions)



    In a multistep business process, the processes are running span of long minutes, days, or months. The process contains multiple organizations and workflows involved. The short running transactions are operations related to business that are completed in few seconds. It contains some external dependencies. These scenarios are known as transactions.

    The behavior of the transactions is known as ACID transactions. The ACID transactions are as explained below:
    1. Atomic: In atomic transactions, all the updates within the transaction are successful or are rolled back. No partial updates are allowed.
    2. Consistent: After all the operations are completed, the data is validated to the business rules.
    3. Isolated: When the user is executing an operation, no partial results can be viewed outside the transactions.
    4. Durable: When the transaction is committed, the data is persisted to survive from the failures.

    Transactional operations within a service



    The transactional operations can either succeed or fail. They are used by a user considering that the result is consistent, even if the operation succeeds or fails. To implement a behavior in WCF, the attribute [ OperationBehavior ( TransactionScopeRequired=true) ] is marked in the service operation. It directs the user to create a new transaction.

    The TransactionScopeRequired=false is used for the operation to execute without the transaction. The transaction does not support the ACID properties. User can show that an operation is complete either implicitly or explicitly. The [ OperationBehavior ( TransactionAutoComplete=true ) ] behavior, the operation is implicitly completed.

    Code:
    [ ServiceContract ]
    public interface IService1
    {
        [ OperationContract ]
        double GetAmount ( string customername );
    
        [ OperationContract ]
        void MoveAmount ( string From , string To, double amount );
    }
    
    public class Service1 : IService1
    {
        [ OperationBehavior ( TransactionScopeRequired = false ) ]
        public double GetAmount ( string customername)
        {
            DBAccess db1 = new DBAccess();
            double amount=db1.GetAmount(CustomerName);
            return amount;
        }
    
        [ OperationBehavior ( TransactionScopeRequired=true, TransactionAutoComplete=true ) ]
        public void MoveAmount ( string From, string To, double amount )
        {
            try
            {
                CashReceived( From, amount);
                CashDeposited( To, amount);
            }
            catch ( Exception ex )
            {
                throw ex;
            }
        }
    
    private void CashReceived  ( string customername, double amount )
    {
        DBAccess db1=new DBAccess();
        db1.CashReceived( customername, amount );
    }
    private void CashDeposited ( string customername, double amount )
    {
        DBAccess db1=new DBAccess();
        db1.CashDeposited( customername, amount );
    }
    
    class DBAccess
    {
        SqlConnection con;
        public DBAccess()
        {
            string c1 = ConfigurationManager.ConnectionStrings[“initialDB”].ConnectionString;
            con = new SqlConnection (c1 );
            con.Open();
        }
    
    public void CashDeposited ( string customername, double amount )
    {
        string sql = string.Format ( “ Deposited values {0} {1} {2} “, customername, amount.ToString(), System.DateTime.Now.ToString() );
        SqlCommand cmd = new SqlCommand (sql, con);
        cmd.ExecuteQuery();
    }
    
    public void CashReceived ( string customername, double amount )
    {
        string sql = string.Format ( “ Withdrawn values {0} {1} {2} “, customername, amount.ToString(), System.DateTime.Now.ToString() );
        SqlCommand cmd = new SqlCommand (sql, con);
        cmd.ExecuteQuery();
    }
    
    public void GetAmount( string customername )
    {
        SqlCommand cmd = new SqlCommand ( “GetDetails”+customername, con );
        SqlDataReader dr = cmd.ExecuteReader();
        dr.Read();
        dr.Close();
        return customername;
    }
    

    Transaction flow across Operations



    When a user wants the transactions to be implemented into the distributed applications, there must be some boundaries specified by the user. In WCF, the flow of transactional information across the service boundaries is known as transaction flow.

    The following steps are to be implemented for the flow of transactional semantics.
    1. (ServiceContract) SessionMode.Required: The service contracts must require sessions because the information is shared between the coordinator and services.
    2. (Operation Behavior) TransactionScopeRequired = true: It is the scope of the transaction. A new transaction is created if there is none present.
    3. (Operation Contract ) TransactionFlowOption.Allowed: Operation contract must allow the transactions information to flow in the message headers.
    4. (Binding Definitation ) TransactionFlow=true: The binding must enable the transaction flow, the transaction information is added in the SOAP header.
    5. (Client) TransactionScope: It initiated the transaction. The client must use the transaction scope to call the service operations.
     

Share This Page