2015-01-19 7 views
1

Я пытаюсь создать клиентское/серверное приложение, которое сможет обмениваться «командами». Дело в том, что серверное приложение обрабатывает некоторые вещи, и я хотел бы, чтобы клиент мог, например, отправить команду «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].

Спасибо, Якуб.

+1

Да, это плохая практика поместить поведение в DataContracts для их цели - это только содержать данные. Также поведение/реализация Pause, Resume и т. Д. Выполняется сервером и не касается клиента (разделение проблем). Ergo, вы не хотите делиться реализацией с клиентом, если в реализацию должны быть внесены изменения, вам также потребуется перераспределить общую сборку для клиента. Используя WCF, вы должны скорее связать ссылку с открытой службой с сервером с клиентом. Это будет использовать WSDL для создания ваших прокси для связи с сервером. –

ответ

1

Если честно, я не думаю, что ICommand с атрибутом атрибута ServiceKnownType хорошо работает для команд.

ServiceKnownType предназначен для поддержки полиморфизма через границы службы в контексте свойств типа, а не поведения.

Сценарий вашей паузы/возобновления будет очень легко реализован с обменом двумя различными определениями DataContract запроса/ответа.

+0

Привет, Том.Итак, что вы предлагаете, я должен создать 2 контракта данных, а затем метод OperationContract, который будет выглядеть так: «Ответ DoCommand (Запрос запроса)», в то время как запрос будет выполнять операцию приостановки/возобновления? – JakubJ

+0

Да, хотя ваш рабочий контракт должен быть явно указан, например: - 'PauseResponse PauseProcessing (команда PauseCommand);' Нет необходимости делать вещи обобщенными в этом примере –

+0

Я вижу. Я просто подумал, что в случае, если у меня будет больше команд, было бы, может быть, более ясно, если я буду придерживаться универсального объявления, а после этого создам объекты с помощью Activator или что-то в этом роде. Но я думаю, я могу придерживаться простых контрактов на операцию. Спасибо за ваш совет :). – JakubJ

Смежные вопросы