Возврат общих типов с использованием контрактов данных в WCF - PullRequest
1 голос
/ 30 марта 2011

У меня есть тип TestResult в сборке, и эта сборка используется двумя приложениями. У меня также есть служба WCF, размещенная в одном приложении (служба Win), которая предоставляет метод, который возвращает экземпляр этого типа TestResult.

Хотя это работает, будет ли хорошей практикой возвращать только типы контактов данных? В будущем могут появиться другие приложения, которым может понадобиться использовать этот сервис, и в идеале я бы хотел избавить от необходимости поставлять DLL с приложением, чтобы оно могло использовать сервис.

Ответы [ 2 ]

2 голосов
/ 30 марта 2011

Прелесть DataContracts (а иногда и их проклятие) в том, что VS может создать объект, который будет выполнять DataContract, без необходимости делать вашу реализацию публичной. Итак, если вы не хотите отправлять DLL, хорошо; когда потребители вашей службы добавляют ссылку на службу, VS создает свой собственный объект TestResults, который реализует ITestResults и определяет средства доступа для DataMembers.

Обратите внимание, что из-за этого поведения лучше всего делать реализации DataContract "анемичными"; вы не можете определить бизнес-логику, которая будет передавать сгенерированную реализацию, поэтому лучше всего настроить их как содержащие только поля или простые свойства. Таким образом, ваш сервис не может делать никаких предположений о том, что любой сгенерированный класс сможет сделать с другой стороны.

РЕДАКТИРОВАТЬ: Если класс или интерфейс, который является ServiceContract, предоставляет метод, который возвращает TestResult как OperationContract, тогда TestResult ДОЛЖЕН быть DataContract, а любые интересующие его свойства или поля должны быть DataMembers. Это не лучшая практика, это обязательно нужно. С другой стороны, независимо от видимости метода в коде на стороне сервера, если метод не является OperationContract, то он невидим для клиента, и TestResult не обязательно должен быть DataContract, ЕСЛИ МЕНЬШЕ другой метод OperationContract принимает или возвращает экземпляр TestResult.

Вы заявили, что возвращаете TestResult в результате вызова службы. На самом деле это звучит так: ваш OperationContract возвращает класс DataContract, который выглядит как TestResult, а вы возвращаете TestResult. Это указывает на то, что существует неявное преобразование, указанное между TestResult и TestResultDataContract, или некоторое поведение на более высоком уровне, которое клонирует TestResult в TestResultDataContract. Все в порядке; преобразование происходит перед возвратом, а DataContract по-прежнему является тем, что фактически выходит из метода обслуживания. Вы можете задокументировать, что происходит, если вы возвращаете TestResult из метода, указывающего, что он возвращает тип TestResultDataContract.

Другая возможность заключается в том, что вы на самом деле не вызываете службу как удаленную службу WCF через сгенерированный клиентский прокси; вы просто создаете экземпляр и вызываете класс, который фактически реализует сервис. Я видел это много раз; все, что требуется, это ссылка на класс реализации, а не на прокси-сервер, и передать привет ошибкам в производственной среде, которых вы не видели в dev. При условии, что вы ДЕЙСТВИТЕЛЬНО ИСПОЛЬЗУЕТЕ клиентский прокси, совершенно нормально ссылаться на ту же реализацию TestResult (или его брата, украшенного DataContract) в клиентском коде, если у вас есть доступ к DLL, содержащей этот контракт на клиенте. Однако весь смысл в том, что в этом нет необходимости; если у вас нет объекта, соответствующего подписи DataContract службы, он будет создан для вас.

0 голосов
/ 31 марта 2011

Может быть, я неправильно понимаю, но звучит так, как будто вы должны определить TestResult как DataContract и продолжить возвращать этот тип из операции службы как обычно.Для приложений, которые имеют доступ к двоичному представлению типа (DLL), они могут ссылаться на эту DLL и использовать службу так же, как вы делаете это сегодня.

Для будущих случаев использования, где это НЕ возможно (или практично) чтобы они имели двоичное представление DataContract, вы можете предоставить конечную точку MEX (и / или использовать поведение serviceMetadata), которая позволит потребителю создать свою собственную копию DataContract.Примером этого процесса может быть «Добавить ссылку на службу» - она ​​засасывает метаданные для вашей службы и, помимо прочего, создает локальную копию DataContracts.

Да, я бы посоветовал эточтобы ваши службы могли предоставлять / использовать только определенные DataContracts или собственные типы (например, строки).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...