【发布时间】: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