Я пытаюсь создать клиентское/серверное приложение, которое сможет обмениваться «командами». Дело в том, что серверное приложение обрабатывает некоторые вещи, и я хотел бы, чтобы клиент мог, например, отправить команду «pause» на сервер.WCF - различная реализация общих типов
Дело в том, что мой менеджер предположил, что наилучшим подходом было бы создать интерфейс (например, ICommand), а затем класс для каждой команды (Пауза, резюме), которая наследуется от ICommand. После этого мы могли бы просто создать объект Pause с атрибутом [DataContract], который будет отправлен серверу. Для этой пургу я попытался использовать общие типы, поэтому я создал сборную сборку, в которой я создал все [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) Клиент хочет, чтобы приостановить процесс, поэтому он создает объект «Пауза», который будет содержать, например, идентификатор процесса. 2) Этот объект передается методу DoCommand(), который создает объект «Пауза» на стороне сервера и запускает его метод «Execute()» с заданными параметрами. 3) Если процесс приостановки завершился хорошо, объект Pause возвращается обратно клиенту (с идентификатором процесса и другими атрибутами) 4) Если клиент получит этот ответ, он будет знать, что процесс был приостановлен eben и запускает его собственный «Выполнить»() "на свой собственный объект Pause, который изменит GUI и так далее.
Таким образом, мой вопрос - как-то возможно, иметь разные реализации контрактов, хранящихся в общей библиотеке на стороне сервера и клиента? Или этот подход вообще не подходит? Из того, что у меня есть, не рекомендуется включать поведение (методы) в [DataContracts], но я думал, что это будет нормально, если я не помечу им атрибутом [DataMember].
Спасибо, Якуб.
Да, это плохая практика поместить поведение в DataContracts для их цели - это только содержать данные. Также поведение/реализация Pause, Resume и т. Д. Выполняется сервером и не касается клиента (разделение проблем). Ergo, вы не хотите делиться реализацией с клиентом, если в реализацию должны быть внесены изменения, вам также потребуется перераспределить общую сборку для клиента. Используя WCF, вы должны скорее связать ссылку с открытой службой с сервером с клиентом. Это будет использовать WSDL для создания ваших прокси для связи с сервером. –