65.9K
CodeProject 正在变化。 阅读更多。
Home

WCF 持久化服务

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.85/5 (8投票s)

2014年10月16日

CPOL

3分钟阅读

viewsIcon

24114

downloadIcon

221

WCF 持久化服务

引言

在这篇文章中,我将描述持久化服务及其在WCF中的实现。

如你所知,HTTP是一个无状态协议。因此,如果我们谈论web应用程序、web服务和WCF,所有这些技术都支持HTTP。这意味着它们是无状态的,或者无法在多个请求之间持久化服务器对象的状体。

在WCF中,持久化服务用于此目的,这意味着它提供了一种在多个请求之间持久化服务对象实例的方法。即使服务重启,持久化服务也会保留服务对象。

现在让我解释持久化服务是如何做到这一点的。

持久化服务将服务对象的实例序列化为XML,并使用GUID作为唯一键将此XML存储在数据库中。客户端将此GUID发送到服务,服务使用此GUID从数据库获取相应的实例来处理该请求。

我们还可以使用会话状态持久化(`InstanceContextMode.PerSession`)在WCF中持久化实例对象。唯一的区别是,会话状态持久化将保留实例,直到服务或客户端重启。由于会话状态持久化将实例存储在内存中,因此当客户端或服务器重启时,它将丢失该对象。但是,持久化服务将实例存储在数据库中,即使服务重启后,也可以使用提供的GUID从数据库获取实例。现在让我们看看在WCF中实现持久化服务的示例。

WCF持久化服务实现

A. 数据库设置

第一步是设置数据库以存储实例,SQL Server已经拥有创建表、模式、用于管理实例的存储过程所需的所有脚本。

  1. 创建一个数据库来存储SQL Server中序列化的实例,并将其命名为“`DurableServiceDB`”。
  2. 现在转到“`C:\Windows\Microsoft.NET\Framework\v3.5\SQL\EN`”位置,并从“`SqlPersistenceProviderSchema.sql`”和“`SqlPersistenceProviderLogic.sql`”文件中获取脚本。

    `SqlPersistenceProviderSchema.sql`包含创建表和模式的脚本,`SqlPersistenceProviderLogic.sql`包含用于存储、检索和删除数据库中实例的存储过程的脚本。

  3. 现在为你的数据库执行以上两个脚本。
    1. 执行以下脚本
      USE DurableServiceDB 
    2. 现在执行`SqlPersistenceProviderSchema.sql`脚本
    3. 现在执行`SqlPersistenceProviderLogic.sql`脚本

接下来,我们将实现持久化服务。

B. 创建持久化服务

  1. 创建一个名为“`MergeStringService`”的WCF服务应用程序。
  2. 将`IServce1.cs`重命名为`ImergeStringDurableService.cs`,并将以下代码粘贴到文件中。
    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. 将`Service1.svc`重命名为“`MergeStringDurableService`”,并更新代码。
    <%@ ServiceHost Language="C#" Debug="true" 
    Service="MergeStringService.MergeStringDurableService" 
    CodeBehind="MergeStringDurableService.svc.cs" %>
  4. 在`MergeServiceDurableService.svc.cs`中添加以下代码。
    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
            }   
        }
    }

    这里`Serializable`属性用于类,因为它需要将实例序列化为XML才能存储在数据库中。它使用了两个新属性

    1. `DurableService`:此属性用于指定持久化服务的实现。
    2. `DurableOperation`:它指定持久化服务公开的函数。它允许指定两个属性
      1. `CanCreateInstance`:将此属性设置为`true`以将实例持久化到数据库中。
      2. `CompletesInstance`:将此属性设置为`true`以从数据库中删除实例。
  5. 更新`web.config`文件如下,并相应地编辑`connectionString`。
    <?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. 现在持久化服务的实现已经完成。我们的最后一步是创建一个客户端应用程序。

C. 创建客户端应用程序

  1. 创建一个名为“`DurableServiceClient`”的控制台应用程序,并运行服务应用程序。
  2. 添加服务引用并将其命名为“`StringOperationService`”。
  3. 现在将以下代码添加到`Program.cs`中。
    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. 现在运行客户端应用程序并输入一些`字符串`,看看合并后的`字符串`。现在停止服务应用程序并再次运行服务。转到客户端应用程序控制台并输入一些要合并的`字符串`。你会发现它将给出整个合并的`字符串`作为输出,这意味着它对这个请求使用了相同的服务实例。
  5. 现在执行查询
    SELECT * FROM [DurableServiceDB].[dbo].[InstanceData]

    它将显示存储在数据库中的实例。

  6. 现在要从数据库中删除服务实例,键入“`Y`”并按Enter键,它将从数据库中删除实例。

因此,即使在重启服务后,持久化服务也会保留实例。

© . All rights reserved.