WCF - 共享类型的不同实现
WCF - different implementation of shared types
我正在尝试设计 client/server 可以交换 "commands" 的应用程序。问题是,服务器应用程序正在处理一些东西,我希望客户端能够向服务器发送命令 "pause"。
事情是,我的经理建议,最好的方法是创建接口(例如 ICommand),然后 class 为将从 ICommand 继承的每个命令(暂停、恢复)创建接口。之后,我们可以简单地创建一个带有 [DataContract] 属性的对象 Pause,它将被发送到服务器。
为此,我尝试使用共享类型,因此我创建了单独的程序集,在其中设计了所有 [DataContracts],以便服务器和客户端都可以使用它们(它们有指向它们的引用)。
在服务器上,我们将有 [OperationContract],它将 [DataContract] 和 return [DataContract] 作为参数,就像这样:
[ServiceKnownType(typeof(PauseServer))]
[ServiceKnownType(typeof(Resume))]
[ServiceContract]
public interface ITestService
{
[OperationContract]
ICommand DoCommand(ICommand command);
}
问题是,除了某些属性之外,我们希望有例如方法 "Execute(param1,param2)",它会执行某些操作 - 此方法会在服务器上执行不同的操作(暂停进程)和不同的在客户端操作(例如更改状态并启用 "Resume" 按钮)。像这样:
[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 对象被 returned 返回给客户端(带有进程 ID 和其他属性)
4) 如果客户端收到此响应,它将知道进程已暂停,并且 运行 它自己的 "Execute()" 方法在其自己的 Pause 对象上,这将更改 GUI 等。
所以我的问题是 - 是否有可能在 server/client 端的公共库中存储不同的合同实现?还是这种方法通常是错误的?据我所知,不建议将行为(方法)包含到 [DataContracts],但我认为如果我不使用 [DataMember] 属性标记它们就可以了。
谢谢你,Jakub。
老实说,我认为带有 ServiceKnownType 属性的 ICommand 想法不太适用于命令。
ServiceKnownType 旨在在类型属性而非行为的上下文中支持跨服务边界的多态性。
通过交换两个不同的 request/response DataContract 定义,您的 Pause/Resume 场景将很容易实现。
我正在尝试设计 client/server 可以交换 "commands" 的应用程序。问题是,服务器应用程序正在处理一些东西,我希望客户端能够向服务器发送命令 "pause"。
事情是,我的经理建议,最好的方法是创建接口(例如 ICommand),然后 class 为将从 ICommand 继承的每个命令(暂停、恢复)创建接口。之后,我们可以简单地创建一个带有 [DataContract] 属性的对象 Pause,它将被发送到服务器。 为此,我尝试使用共享类型,因此我创建了单独的程序集,在其中设计了所有 [DataContracts],以便服务器和客户端都可以使用它们(它们有指向它们的引用)。
在服务器上,我们将有 [OperationContract],它将 [DataContract] 和 return [DataContract] 作为参数,就像这样:
[ServiceKnownType(typeof(PauseServer))]
[ServiceKnownType(typeof(Resume))]
[ServiceContract]
public interface ITestService
{
[OperationContract]
ICommand DoCommand(ICommand command);
}
问题是,除了某些属性之外,我们希望有例如方法 "Execute(param1,param2)",它会执行某些操作 - 此方法会在服务器上执行不同的操作(暂停进程)和不同的在客户端操作(例如更改状态并启用 "Resume" 按钮)。像这样:
[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 对象被 returned 返回给客户端(带有进程 ID 和其他属性) 4) 如果客户端收到此响应,它将知道进程已暂停,并且 运行 它自己的 "Execute()" 方法在其自己的 Pause 对象上,这将更改 GUI 等。
所以我的问题是 - 是否有可能在 server/client 端的公共库中存储不同的合同实现?还是这种方法通常是错误的?据我所知,不建议将行为(方法)包含到 [DataContracts],但我认为如果我不使用 [DataMember] 属性标记它们就可以了。
谢谢你,Jakub。
老实说,我认为带有 ServiceKnownType 属性的 ICommand 想法不太适用于命令。
ServiceKnownType 旨在在类型属性而非行为的上下文中支持跨服务边界的多态性。
通过交换两个不同的 request/response DataContract 定义,您的 Pause/Resume 场景将很容易实现。