WCF: Как мне поддерживать классы контрактов на клиенте и сервере?

Я работаю над приложением WCF с сервером и клиентом (естественно). В серверном проекте я определил классы с атрибутами contract.

Теперь, когда сервер готов, я добавил ссылку на сервис, и он создал для меня прокси. Я использовал его, и он работал нормально.

Вопрос, который я хочу задать, - это нормально, если я создам общую DLL, которая содержит определения классов с атрибутами контракта, и буду использовать ее как для сервера, так и для клиента (вместо использования классов, созданных для клиента Visual Studio). Если я использую общие классы, мне не нужно беспокоиться о преобразовании коллекций универсальных шаблонов в массивы при автоматической генерации кода. Это глупо? Является ли это возможным? Кто-нибудь делал это раньше? Это нормально?

Сценарий развертывания таков, что в защищенной интрасети будет ограниченное (небольшое) количество клиентов, и можно обновлять существующие клиенты всякий раз, когда происходит изменение на сервере.


person Hemant    schedule 21.03.2009    source источник


Ответы (4)


Такой подход хорош (я его довольно часто использую) до тех пор, пока вы контролируете клиента. Он не будет работать (очевидно) с java-клиентами и т. Д. Если вы знаете, что вам никогда не понадобится поддержка клиентов, отличных от .NET, тогда он может быть мощным, но он нарушает некоторые пуристические правила SOA. В частности, да, сценарий интрасети - это тот, где я мог бы рассмотреть этот подход.

И svcutil.exe, и IDE имеют возможность повторно использовать типы из существующих сборок, чтобы сделать именно это.

edit еще одно преимущество этого подхода заключается в том, что вы хотите использовать одну и ту же логику проверки на клиенте, не кодируя ее дважды, например IDataErrorInfo и т. д.

person Marc Gravell    schedule 21.03.2009

Если вас беспокоит только преобразование коллекций в массивы, вам не нужно заходить так далеко. Кнопка «Дополнительно» в диалоговом окне «Добавить ссылку на службу» позволяет указать, какой тип использовать для подобных случаев. Вы можете использовать List вместо T [].

person John Saunders    schedule 21.03.2009
comment
Дело не только в этом. Он обновляет ссылку на службу всякий раз, когда в этих классах происходит изменение. И еще удобнее, когда в среде IDE создается меньше кода. Я просто хотел убедиться, что если я буду следовать этому подходу, я не сделаю что-то табу или ужасное нарушение стандартов / руководящих принципов. - person Hemant; 21.03.2009
comment
Что ж, вам не нужно обновлять ссылки на службы всякий раз, когда вы вносите изменения - только когда вы меняете контракт. Надеюсь, ты не будешь делать это очень часто. Вы также можете рассмотреть возможность использования Service Factory (codeplex.com/servicefactory). Это обновило бы клиента и сервис вместе. - person John Saunders; 21.03.2009

Сохранение типов контрактов в отдельной общей сборке - действительно хорошая идея. Это дает вам возможность добавить адаптеры, например, для преобразования между типы контрактов и другие бизнес-объекты, которые у вас могут быть, или посредники и т. д. между этими типами.

Имеет смысл использовать общие типы , даже если вы не контролируете всех клиентов. Предположим, у вас есть служба, которую используют внутренние приложения, использующие .NET, а также доверенные третьи стороны в партнерской компании. Партнерские приложения используют Java, Ruby или Python. В этом случае партнер не будет иметь доступа к совместно используемым типам, но, полагаясь на WSD / XSD, сможет развернуть свою собственную библиотеку типов на стороне клиента. Это не должно помешать вам предоставить хороший пакет общих типов вашим внутренним разработчикам.

Эта рекомендация по совместному использованию типов также применима, когда вы используете интерфейс REST, а не WS / SOAP. В REST отсутствует WSDL, но XSD (или аналогичный) все равно будет использоваться для описания типов сообщений, которыми обмениваются сервер и его клиенты. Таким образом, никаких изменений в рекомендациях, независимо от того, используете ли вы SOAP или REST.

РЕДАКТИРОВАТЬ: И это применимо независимо от того, используете ли вы .NET, Java или что-то еще. Если вы контролируете оба конца провода и платформы одинаковы, то да, вам следует использовать общие типы. Почему бы и нет?

person Cheeso    schedule 31.03.2009

Создав отдельные сборки для хранения контрактов, вы можете ссылаться на эти сборки и использовать их для создания каналов (используя ChannelFactory) в службу от клиента. Благодаря этому вам больше не нужно обновлять «ссылку на услугу» каждый раз, когда вы меняете контракт на обслуживание.

ChannelFactory<IContract> factory = 
    new ChannelFactory<IContract>("endpointName");
person David Walschots    schedule 31.03.2009