我正在尝试设计客户端/服务器应用程序,它可以交换“命令”。问题是,服务器应用程序正在处理一些东西,我希望客户端能够例如向服务器发送命令“pause”。
我的经理建议,最好的方法是创建接口(例如ICommand),然后为每个从ICommand继承的命令(Pause,Resume)创建类。之后,我们可以简单地创建一个带有[DataContract]属性的对象Pause,该属性将被发送到服务器。 对于那个purpouse,我尝试使用共享类型,所以我创建了seprated程序集,我在其中设计了所有[DataContracts],以便服务器和客户端都可以使用它们(它们具有引用它们的引用)。
在服务器上,我们将[OperationContract],将[DataContract]作为参数并返回[DataContract],如下所示:
[ServiceKnownType(typeof(PauseServer))]
[ServiceKnownType(typeof(Resume))]
[ServiceContract]
public interface ITestService
{
[OperationContract]
ICommand DoCommand(ICommand command);
}
问题是,除了一些属性之外,我们希望有例如方法“执行(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)客户端想要暂停该过程,因此它创建对象“暂停”,该对象将包含例如进程的ID。 2)此对象传递给DoCommand()方法,该方法在服务器端创建对象“Pause”并使用给定参数运行其“Execute()”方法。 3)如果暂停过程结束,Pause对象将返回给客户端(具有进程ID和其他属性) 4)如果客户端获得此响应,它将知道该进程已暂停eben并在其自己的Pause对象上运行其自己的“Execute()”方法,这将改变GUI等等。
所以我的问题是 - 在某种程度上可能,在服务器/客户端的公共库中存储不同的合同实现吗?或者这种方法总体上是错误的吗?根据我的观点,不建议在[DataContracts]中包含行为(方法),但我认为如果我不用[DataMember]属性标记它们就没问题。
谢谢你,Jakub。
答案 0 :(得分:1)
老实说,我认为具有ServiceKnownType属性思想的ICommand不适用于命令。
ServiceKnownType旨在支持类型属性上下文中跨服务边界的多态,而不是行为。
通过交换两个不同的请求/响应DataContract定义,可以非常轻松地实现暂停/恢复方案。