【问题标题】:Where do data structures belong in a WCF application?数据结构在 WCF 应用程序中属于哪里?
【发布时间】:2010-12-24 18:23:54
【问题描述】:

假设我有一个使用 WCF 服务进行幕后处理的 Web 项目,以及一个处理 Web 请求的 MVC 2 项目(我猜这将是 WCF 客户端)。 WCF 服务生成数据并处理预先生成的数据(处理可能会异步进行)。这两件事是 Visual Studio 中同一解决方案中的不同项目。

现在,我不确定将表示服务生成的内容以及客户端需要处理并发送到用户浏览器的内容的数据结构放在哪里。目前它们都在标有[DataContract] 的服务接口(端点接口?不确定它的确切名称)中(还不确定它是做什么的)。但是,由于 MVC 应用程序在一个单独的项目中,我必须重新定义那里的所有数据结构——这有必要吗?我应该把这些结构放在解决方案的其他地方吗?接口越来越多的类定义——我是否能够制作某种共享资源,其中包含项目之间的共享数据结构? [DataContract] 部分呢——如果类是在其他地方定义的,我还需要以某种方式在接口中填充它吗?

抱歉,如果我不太有道理或非常含糊不清。我以前从未使用过这些微软技术,所以我还是很迷茫。我只是边走边学。

【问题讨论】:

    标签: c# wcf


    【解决方案1】:

    我喜欢这样构建我的 WCF 解决方案:

    合同(类库)
    包含所有服务、操作、故障和数据合同。可以在纯 .NET 到 .NET 方案中的服务器和客户端之间共享。这是您放置数据结构类的地方,以便生态系统中的所有项目都可以使用它。

    服务实现(类库)
    包含实现服务的代码,以及实现此目的所需的任何支持/帮助方法。没有别的了。

    服务主机(可选 - 可以是 Winforms、控制台应用程序、NT 服务)
    包含用于调试/测试或可能还用于生产的服务主机。

    这基本上给了我服务器端的东西。

    在客户端:

    客户端代理(类库)
    我喜欢将我的客户端代理打包到一个单独的类库中,这样它们就可以被多个实际的客户端应用程序重用。这可以使用 svcutil 或“添加服务引用”并手动调整生成的可怕的 app.config 来完成,或者通过使用 ClientBase<T>ChannelFactory<T> 构造手动实现客户端代理(共享合同程序集时)。

    1-n 个实际客户(任何类型的应用)
    通常只会引用客户端代理程序集,或者也可能会引用合同程序集,如果它被共享的话。这可以是 ASP.NET、WPF、Winforms、控制台应用程序、其他服务 - 你可以命名它。

    这样;我有一个漂亮而干净的布局,我一遍又一遍地使用它,我真的认为这让我的代码更干净,更容易维护。

    这受到了 Miguel Castro 在 DotNet Rocks TV 上与 Carl Franklin 合作的 Extreme WCF screen cast 的启发 - 强烈推荐屏幕演员!

    【讨论】:

      【解决方案2】:

      将您的数据对象放在另一个单独的项目中(创建它时选择类库)并从 WCF 和 MVC2 中引用它们(除了重复,我认为否则不可能让它工作)。

      [DataContract] 必须用于装饰数据对象类,无论它们在哪里。

      我不确定你说“[DataContract] 部分怎么样——我还需要以某种方式在界面中填充它”的意思...你能提供一些示例代码吗?

      作为参考,以下是我过去参与的项目中的一些代码:

      这是在项目Server.Contracts

      namespace Server.Contracts.DataContracts.Mapped
      {
          using System;
          using System.Runtime.Serialization;
      
          [DataContract]
          public class ConfigSetting : BindableDataContract
          {
              [DataMember]
              public string Name { get; set; }
      
              [DataMember]
              public string Value { get; set; }
      
              [DataMember]
              public DateTime ModifiedOn { get; set; }
      
              public override object Clone()
              {
                  return new ConfigSetting
                         {
                             ModifiedOn = this.ModifiedOn,
                             Name = this.Name,
                             Value = this.Value,
                         };
              }
          }
      }
      

      这也在Server.Contracts:

      namespace Server.Contracts.ServiceContracts
      {
          using System;
          using System.Net.Security;
          using System.ServiceModel;
          using Common.Constants.ServiceModel;
          using Common.LogClient;
      
          /// <summary>
          /// Interface that defines the log service contract.
          /// </summary>
          [ServiceContract(
          Name = ServiceContract.LogServiceName,
          Namespace = ServiceContract.LogServiceNamespace,
          ProtectionLevel = ProtectionLevel.None, 
          SessionMode = SessionMode.NotAllowed)]
          public interface ILogService
          {
              [OperationContract(Name = "Deferred", IsOneWay = true)]
              void Deferred(LogSeverity severity, DateTime eventTimeUtc, string actor,
                            uint? deviceId, string message, string stackTrace);
          }
      }
      

      此项目引用自这两个其他项目,其中包括:

      • 客户
      • Server.Implementation(例如,ILogService 已实现)

      【讨论】:

      • 如何引用它们?我的意思是……我可以像往常一样导入一个命名空间吗……?另外,我需要基类和属性类型的装饰器,还是只需要接口中返回/参数类型中使用的类?
      • 添加一个 VS 引用(右键单击项目 -> 添加引用... -> 项目选项卡 -> 选择带有合同的项目)然后您可以简单地导入命名空间。不确定您提到的“基类”是哪些,但原则上答案是肯定的:您需要 DataContractDataMember 在层次结构中存在要通过 WCF 传递的属性的任何位置。
      • 啊,这很有道理,谢谢。 Server.Contracts.DataContracts.Mapped 是否需要专门作为 WCF 项目?我在一个 C# 类库中创建了一个 Contracts.Data 命名空间,但我似乎找不到 DataContract -- 并且 System.ServiceModel 等似乎不可用
      • DataContract 在汇编中 System.Runtime.Serialization。您需要一个类库,但您还需要添加对序列化程序集的引用(如上面的示例,但在“.NET”选项卡中)。顺便说一句,我认为您应该先花一些时间来学习有关 .NET 开发的这些基本步骤,这将节省您将来浪费的大量时间。
      • 好吧,我想我明白了。另外,学习是我正在做的:)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-05
      • 1970-01-01
      • 2017-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多