【问题标题】:WCF - different implementation of shared typesWCF - 共享类型的不同实现
【发布时间】:2015-01-19 15:49:26
【问题描述】:

我正在尝试设计能够交换“命令”的客户端/服务器应用程序。问题是,服务器应用程序正在处理一些东西,我希望客户端能够向服务器发送命令“暂停”。

问题是,我的经理建议,最好的方法是创建接口(例如 ICommand),然后为从 ICommand 继承的每个命令(Pause、Resume)创建类。之后,我们可以简单地创建一个带有 [DataContract] 属性的对象 Pause,它将被发送到服务器。 为此,我尝试使用共享类型,因此我创建了单独的程序集,我在其中设计了所有 [DataContracts],以便服务器和客户端都可以使用它们(它们有指向它们的引用)。

在服务器上,我们将拥有 [OperationContract],它将 [DataContract] 作为参数并返回 [DataContract],如下所示:

[ServiceKnownType(typeof(PauseServer))]
[ServiceKnownType(typeof(Resume))]
[ServiceContract]
public interface ITestService
{
     [OperationContract]
    ICommand DoCommand(ICommand command);
}

问题是,除了一些属性之外,我们希望有例如方法“Execute(param1,param2)”,它会执行某些操作 - 这个方法会在服务器上执行不同的操作(暂停进程)和客户端的不同操作(例如更改状态并启用“恢复”按钮)。像这样:

[DataContract(Namespace="PauseContract")]
public class Pause
{
    string _param1;
    int _param2;

    public void Execute()
    {
       // DO SOMETHING HERE
    }

    [DataMember]
    public string Param1
    {
        get
        {
            return _param1;
        }
        set
        {
            this._param1 = value;
        }
    }

    [DataMember]
    public int Param2
    {
        get
        {
            return _param2;
        }
        set
        {
            this._param2 = value;
        }
    }
}

最后,整个过程是这样的: 1) 客户想要暂停进程,因此它创建了对象“Pause”,该对象将包含例如进程的 ID。 2) 该对象被传递给 DoCommand() 方法,该方法在服务器端创建对象“Pause”并使用给定参数运行其“Execute()”方法。 3)如果Pausing过程结束良好,则将Pause对象返回给客户端(带有进程ID和其他属性) 4) 如果客户端得到这个响应,它将知道进程已经暂停并在它自己的 Pause 对象上运行它自己的“Execute()”方法,这会改变 GUI 等等。

所以我的问题是 - 是否有可能在服务器/客户端的公共库中存储不同的合同实现?还是这种方法总体上是错误的?据我所知,不建议在 [DataContracts] 中包含行为(方法),但我认为如果我不使用 [DataMember] 属性标记它们就可以了。

谢谢你,贾库布。

【问题讨论】:

  • 是的,将行为放在 DataContracts 中是不好的做法,因为它们的目的只是包含数据。此外,暂停、恢复等的行为/实现由服务器完成,与客户端无关(关注点分离)。因此,您不想与客户端共享实现,因为如果要对实现进行更改,您还需要将共享程序集重新部署到客户端。使用 WCF,您应该将公开的服务引用从服务器链接到您的客户端。这将使用 WSDL 生成代理以与服务器通信。

标签: c# wcf datacontract


【解决方案1】:

老实说,我不认为带有 ServiceKnownType 属性的 ICommand 理念适用于命令。

ServiceKnownType 旨在在类型属性而非行为的上下文中支持跨服务边界的多态性。

通过交换两个不同的请求/响应 DataContract 定义,您的暂停/恢复场景将非常容易实现。

【讨论】:

  • 你好汤姆。所以你的建议是我应该创建 2 个数据契约,然后是 OperationContract 方法,看起来像这样:“Response DoCommand(Request request)”,而请求将执行暂停/恢复操作?
  • 是的,尽管您的操作合同应该明确命名,例如:-PauseResponse PauseProcessing(PauseCommand command); 在这种情况下没有必要使事情通用
  • 我明白了。我只是想,如果我有更多命令,如果我坚持通用声明,然后使用 Activator 或其他东西创建对象,可能会更清楚。但我想我现在可以坚持简单的运营合同。谢谢你的建议:)。
  • 即使您实现了通用处理程序并且需要添加新类型的命令,也很难避免重新编译。
猜你喜欢
  • 2012-04-10
  • 2012-02-06
  • 1970-01-01
  • 2014-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-15
相关资源
最近更新 更多