Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

WCF Durable Service

4.85/5 (8 votes)
16 Oct 2014CPOL3 min read 23.8K   200  
WCF Durable service

Introduction

In this article, I will describe durable services and its implementation in WCF.

As you might know, HTTP is a stateless protocol. So if we talk about web application, web service and WCF, all these technologies support HTTP. It means they are stateless or not able to persist the state of server object between multiple requests.

In WCF, durable services serves for this purpose means it provides a way to persist the instance of service object between multiple requests. Durable services persist the service object even after the service restarts.

Now let me explain how durable services do this.

Durable services serialize the instance of service object to XML and stores this XML in the database with a GUID as a unique key. Client sends this GUID to the service, service use this GUID to get the corresponding instance from database to serve that request.

We can also persist the Instance object in WCF using session state persistence as InstanceContextMode.PerSession. The only difference is that session state persistence will persist the instance until service or client is restarted. As session state persistence stores the instance in memory, so it will lose the object as client or server will restart. But durable service stores the instance in database and can get the instance from database using provided GUID even after the service is restarted. Now let's have a look at the implementation of durable service in WCF.

WCF Durable Services Implementation

A. Database Set Up

First step is to set up the database to store the instances, SQL server already has all the scripts required to create the Table, Schema, Stored Procedure for managing the instances:

  1. Create a database to store the serialized instances in SQL Server and name it “DurableServiceDB”.
  2. Now go to the location “C:\Windows\Microsoft.NET\Framework\v3.5\SQL\EN” and get the scripts from “SqlPersistenceProviderSchema.sql” and “SqlPersistenceProviderLogic.sql” files.

    SqlPersistenceProviderSchema.sql contains the script to create the tables and schema and SqlPersistenceProviderLogic.sql contains the script for the stored procedures used to store, retrieve and remove instances from database.

  3. Now execute the above 2 scripts for your database.
    1. Execute the below script:
      SQL
      USE DurableServiceDB 
    2. Now execute SqlPersistenceProviderSchema.sql script
    3. Now execute SqlPersistenceProviderLogic.sql script

Now our next step is to implement durable service.

B. Create Durable Service

  1. Create a WCF Service application named “MergeStringService”.
  2. Rename the IServce1.cs as ImergeStringDurableService.cs and paste the below code in the file:
    C#
    using System.ServiceModel;
    namespace MergeStringService
    {
        [ServiceContract]
        public interface IMergeStringDurableService
        {
            //To Persist the instance in db
            [OperationContract]
            void PersistServiceInstance();
    
            [OperationContract]
            void MergeString(string str);
    
            [OperationContract]
            string GetMergedString();
    
            //To Remove instance from db
            [OperationContract]
            void RemoveServiceInstance();
        }
    }
  3. Rename the Service1.svc as “MergeStringDurableService” and update the code as:
    HTML
    <%@ ServiceHost Language="C#" Debug="true" 
    Service="MergeStringService.MergeStringDurableService" 
    CodeBehind="MergeStringDurableService.svc.cs" %>
  4. Add the following code in MergeServiceDurableService.svc.cs:
    C#
    using System;
    using System.ServiceModel.Description;
    
    namespace MergeStringService
    {
    [Serializable]
        [DurableService()]
        public class MergeStringDurableService : IMergeStringDurableService
        {
            private string mergedString;
    
            [DurableOperation(CanCreateInstance = true)]
            public void PersistServiceInstance()
            {     
                //It will create and store the Instance in db
            }
    
            [DurableOperation()]
            public void MergeString(string str)
            {
                mergedString += str;
            }
    
            [DurableOperation()]
            public string GetMergedString()
            {
                return mergedString;
            }
    
            [DurableOperation(CompletesInstance = true)]
            public void RemoveServiceInstance()
            {
                //It will remove instance from DB
            }   
        }
    }

    Here Serializable attribute is used for class because it requires to serialize the instance to XML to store in database. It uses two new attributes:

    1. DurableService: This attribute is used to specify the implementation of durable service.
    2. DurableOperation: It specifies the functions exposed by durable service. It allows to specify 2 properties:
      1. CanCreateInstance: Set this property to true to persist the instance in db.
      2. CompletesInstance: Set this property to true to remove instance from db.
  5. Update the web.config file as below and edit the connectionString accordingly:
    XML
    <?xml version="1.0"?>
    <configuration>
      <connectionStrings>
        <add name="StringServiceDB" 
        connectionString="Data Source=MyMachine\SQLEXPRESS;
        Initial Catalog=StringServiceDB;Integrated Security=True"/>
      </connectionStrings>
      <system.serviceModel>
        <services>
          <service name="MergeStringService.MergeStringDurableService" 
          behaviorConfiguration="DurableServiceBehavior">
            <endpoint address="" binding="wsHttpContextBinding" 
            bindingConfiguration="DurableServiceBindingConfig" 
            contract="MergeStringService.IMergeStringDurableService">
              <identity>
                <dns value="localhost"/>
              </identity>
            </endpoint>
          </service>
        </services>
        <behaviors>
          <serviceBehaviors>
            <behavior name="DurableServiceBehavior">
              <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
              <serviceDebug includeExceptionDetailInFaults="true"/>
              <persistenceProvider type="System.ServiceModel.Persistence.SqlPersistenceProviderFactory, 
              System.WorkflowServices, Version=3.5.0.0, Culture=neutral,
              PublicKeyToken=31bf3856ad364e35" connectionStringName="StringServiceDB" 
              persistenceOperationTimeout="00:00:10" 
              lockTimeout="00:01:00" serializeAsText="true"/>
            </behavior>
          </serviceBehaviors>
        </behaviors>
        <bindings>
          <wsHttpContextBinding>
            <binding name="DurableServiceBindingConfig">
              <security mode="None"/>
            </binding>
          </wsHttpContextBinding>
        </bindings>
      </system.serviceModel>
      <system.web>
        <compilation debug="true"/>
      </system.web>
    </configuration>
  6. Now durable service implementation is done. Our final step is to create a client application.

C. Create Client Application

  1. Create a console application named “DurableServiceClient” and run the service application.
  2. Add the service reference and name it “StringOperationService”.
  3. Now add the below code to Program.cs:
    C#
    using System;
    using DurableServiceClient.StringOperationService;
    
    namespace DurableServiceClient
    {
        class Program
        {
            static MergeStringDurableServiceClient serviceClient;
    
            static void Main(string[] args)
            {
                serviceClient = new MergeStringDurableServiceClient();
    
                //Store the Instance in database
                serviceClient.PersistServiceInstance();
                Console.WriteLine("Instance stored in Database as XML.");
    
                while (true)
                {
                    Console.WriteLine("Want to clear Instance ? (Y/N)");
                    string selectedOption = Console.ReadLine();
    
                    if (selectedOption.ToUpper().Equals("Y"))
                    {
                        //To remove instance from database
                        serviceClient.RemoveServiceInstance();
                        Console.WriteLine("Instance removed from database.");
                        break;
                    }
                    else
                    {
                        Console.WriteLine("Please enter the string to merge: ");
                        //Merge the string
                        serviceClient.MergeString(Console.ReadLine());
                        //To display merged string
                        Console.WriteLine("Merged String: {0}", serviceClient.GetMergedString());
                    }
                }
    
                Console.ReadLine();
            }
        }
    }
  4. Now run the client application and input some strings and have a look at the merged string. Now stop the service application and again run the service. Go to the client application console and input some string to merge. You will find that it will give the whole merged string as output, means it uses the same service instance for this request.
  5. Now execute the query:
    SQL
    SELECT * FROM [DurableServiceDB].[dbo].[InstanceData]

    It will show you the instances stored in database.

  6. Now to remove service instance from db, Type “Y” and press Enter key, it will remove the Instance from db.

Thus durable service persists the instances even after restarting the service.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)