Task 2: Enable Persistence for the Durable Service

Download sample

In this task, you will decorate the service you created in Task 1 with attributes that enable you to persist the state of your service after every successful operation invocation.

To decorate the service with durable service attributes

  1. Open Service1.cs (or Service1.vb if you created a Visual Basic solution).

  2. In the Solution Explorer pane, under the SimpleDurableService project node, right-click the References subfolder and select Add Reference.

  3. In the Add Reference dialog box, under the .NET tab, select System.WorkflowServices and click OK.

  4. Add the following using statement in your C# source file:

using System.ServiceModel.Description;

If you created a Visual Basic solution, right-click the SimpleDurableService project node and select Properties. Select the References tab, and under Imported Namespaces, check System.ServiceModel.Description.

  1. To persist your service, you must decorate the Service1 class with the DurableServiceAttribute and SerializableAttribute attributes as shown in the following example.
<Serializable()> _
<DurableService()> _
Public Class Service1
    Implements IService1
    '.... The class definition was omitted for clarity.
End Class
[Serializable]
[DurableService]
public class Service1 : IService1
{
    // The class definition was omitted for clarity.
}
  1. The DurableServiceAttribute attribute specifies that state information for your WCF service can be persisted to a persistence store, such as a database or file. Also, the service type must be serializable so that it can be transmitted to the persistence store.

  2. Decorate the service operations with the DurableOperationAttribute attribute as shown in the following example. This attribute specifies that the service instance state will be saved after the operation has completed.

<DurableOperation(CanCreateInstance:=True)> _
Public Function Add(ByVal n1 As Integer) As Integer Implements IService1.Add
    currentValue += n1
    Return currentValue
End Function

<DurableOperation(CompletesInstance:=True)> _
Public Sub EndPersistence() Implements IService1.EndPersistence

End Sub

<DurableOperation()> _
Public Function Multiply(ByVal n1 As Integer) As Integer Implements IService1.Multiply
    currentValue *= n1
    Return currentValue
End Function

<DurableOperation()> _
Public Function Subtract(ByVal n1 As Integer) As Integer Implements IService1.Subtract
    currentValue -= n1
    Return currentValue
End Function
[DurableOperation(CanCreateInstance = true)]
public int Add(int n1)
{
    return (currentValue += n1);
}

[DurableOperation]
public int Subtract(int n1)
{
    return (currentValue -= n1);
}

[DurableOperation]
public int Multiply(int n1)
{
    return (currentValue *= n1);
}

[DurableOperation(CompletesInstance = true)]
public void EndPersistence()
{
}

The CanCreateInstance and CompletesInstance properties specify that the durable service instance will either be created or completed after the decorated operation has successfully completed. In this tutorial, several operations have the first and last operations controlling the behavior of the service instance.

Operations that are decorated with the DurableOperationAttribute attribute set to default values can only persist state information to an existing service instance entry in the persistence store. However, if you create a service contract where System.ServiceModel.SessionMode.NotAllowed is set to true, every DurableOperationAttribute attribute must have the CanCreateInstance property set to true.

Now that your service is decorated with the proper attributes, you must set up your configuration file and reference the persistence store you want to use.

To configure your durable service

  1. Open App.config.

  2. Modify the endpoint configuration settings to reference a context binding, such as WSHttpContextBinding.

    <endpoint address ="" binding="wsHttpContextBinding" contract="SimpleDurableService.IService1" />
    

    Context bindings must be used because a DurableOperationContext is used by the client to identify a specific service instance. After invoking a request/response operation and receiving a response from the service, the client will use the InstanceId value on each subsequent operation invocation so that the client associates itself with the correct service instance. If this tracking mechanism was not used, then when a service instance is either shut down or disconnected from the client, the client would not be able to reestablish a connection to a specific service instance.

  3. Add the following child node to your behavior node.

    <behaviors>
          <serviceBehaviors>
            <behavior name="SimpleDurableService.Service1Behavior">
              <!-- To avoid disclosing metadata information, 
              set the following value to false and remove the preceding metadata endpoint before deployment. -->
              <serviceMetadata httpGetEnabled="True"/>
              <!-- To receive exception details in faults for debugging purposes, 
              set the following value to true. Set the value to false before deployment 
              to avoid disclosing exception information. -->
              <serviceDebug includeExceptionDetailInFaults="False" />
              <persistenceProvider type="System.ServiceModel.Persistence.SqlPersistenceProviderFactory, System.WorkflowServices, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                                   connectionStringName="DurableServiceStore" 
                                   persistenceOperationTimeout = "00:00:10"
                                   lockTimeout="00:01:00"
                                   serializeAsText="true"/>
    
            </behavior>
          </serviceBehaviors>
        </behaviors>
    

    The PersistenceProviderElement defines the type of PersistenceProvider that your service will use. In this tutorial, the SqlPersistenceProviderFactory is used to create a new instance of the PersistenceProvider type that connects to a SQL database. Whenever the Add operation is invoked and successfully completes, a new service instance will be created and its state information will be stored in the SQL database.

  4. Add the connection string for the SQL database that your service instance will use for persistence.

      </system.serviceModel>
      <connectionStrings>
        <add name="DurableServiceStore" connectionString="Data Source=localhost\SQLEXPRESS;Initial Catalog=NetFx35Samples_DurableServiceStore;Integrated Security=SSPI"/>
      </connectionStrings>
    </configuration>
    

Note

This tutorial uses the same database that is used for the Durable Workflow Services Sample; therefore, the connection string is the same. To allow access to the durable store, run the Createstores.cmd script from One-Time Setup Procedure for the Windows Communication Foundation Samples.

In the next task, you will create a client that can access your durable service.

See Also

Tasks

Task 1: Define and Implement the Durable Service Contract

Other Resources

Task 3: Create a Durable Service Client
Tutorial: Create a Durable Service

Copyright © 2007 by Microsoft Corporation. All rights reserved.
Last Published: 2010-03-04