WCF ChannelFactory против генератора прокси

Просто интересно, при каких обстоятельствах вы предпочитаете генерировать прокси-сервер из службы WCF, если вы можете просто вызвать вызовы с помощью ChannelFactory?

Таким образом вам не придется создавать прокси-сервер и беспокоиться о восстановлении прокси-сервера при обновлении сервера?

Спасибо

Ответ 1

Существует 3 основных способа создания клиента WCF:

  • Пусть Visual Studio сгенерирует ваш прокси. Этот авто генерирует код, который подключается к службе, читая WSDL. Если служба по какой-либо причине изменяется, вам необходимо ее восстановить. Большим преимуществом этого является то, что его легко настроить - у VS есть мастер, и все это автоматически. Недостатком является то, что вы полагаетесь на VS, чтобы выполнить всю тяжелую работу, и вы теряете контроль.

  • Используйте ChannelFactory с известным интерфейсом. Это зависит от наличия у вас локальных интерфейсов, описывающих сервис (контракт на обслуживание). Большим преимуществом является то, что вы можете намного легче управлять изменениями - вам все равно придется перекомпилировать и исправить изменения, но теперь вы не обновляете код, вы ссылаетесь на новые интерфейсы. Обычно это используется, когда вы контролируете как сервер, так и клиент, поскольку они могут быть намного легче издеваться над модульным тестированием. Однако интерфейсы могут быть написаны для любой службы, даже для REST, - посмотрите этот API Twitter.

  • Напишите свой собственный прокси - это довольно легко сделать, особенно для служб REST, используя HttpClient или WebClient. Это дает вам самый мелкий контроль над зерном, но за счет множества API-сервисов, работающих в строках. Например: var content = new HttpClient().Get("http://yoursite.com/resource/id").Content; - если детали изменения API не будут встречаться с ошибкой до времени выполнения.

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

Вариант 2 должен быть идеальным, но каналы слишком ограничены - например, они полностью теряют содержимое HTTP-ошибок. При этом наличие интерфейсов, которые описывают услугу, намного проще кодировать и поддерживать.

Ответ 2

Я использую ChannelFactory вместе с методом MetadataResolver.Resolve. Конфигурация клиента беспокоит, поэтому я получаю свою службу ServiceEndpoint с сервера.

Когда вы используете ChannelFactory (Of T), T является либо исходным контрактом, который вы можете получить из справки в вашем проекте или сгенерированном экземпляре контракта. В некоторых проектах я сгенерировал код из Service Reference, потому что я не мог добавить ссылку на dll контракта. Вы даже можете создать асинхронный контракт с ссылкой на службу и использовать этот контрактный интерфейс с ChannelFactory.

Основной смысл использования ChannelFactory для меня состоял в том, чтобы избавиться от информации конфигурации клиента WCF. В приведенном ниже примере кода вы можете увидеть, как достичь WCF-клиента без конфигурации.

Dim fixedAddress = "net.tcp://server/service.svc/mex"
Dim availableBindings = MetadataResolver.Resolve(GetType(ContractAssembly.IContractName), New EndpointAddress(fixedAddress))
factoryService = New ChannelFactory(Of ContractAssembly.IContractName)(availableBindings(0))
accesService = factoryService.CreateChannel()

В моем окончательном проекте, доступные флажки проверяются на использование net.tcp или net.pipe, если они доступны. Таким образом, я могу использовать лучшее доступное связывание для моих нужд. Я полагаюсь только на то, что на сервере существует конечная точка метаданных.

Я надеюсь, что это поможет

Кстати, это делается с помощью .NET 3.5. Однако он работает и с 4.0.

Ответ 3

Хорошо, чтобы использовать ChannelFactory<T>, вы должны быть готовы разделить контрактные сборки между сервисом и клиентом. Если с вами все в порядке, то ChannelFactory<T> может сэкономить некоторое время.

Ответ 4

Прокси-сервер будет строить асинхронные функции, для которых это хорошо.

Ответ 5

Мой ответ - это своего рода резюме ответов Keith и Эндрю Хэра.

Если вы не контролируете сервер, но имеете только WSDL/URL-генерировать прокси-сервер, используя Visual Studio или svcutil. (Обратите внимание, что Visual Studio иногда терпит неудачу, когда svcutil работает лучше).

Когда вы управляете сервером и клиентом, обменивайтесь интерфейсами/контрактами и звоните в ChannelFactory
.

Ответ 6

Это не просто вопрос времени. Использование созданного WSDL-прокси опасно, потому что если вы забудете обновить ссылку на службу, вы можете оставить решение в противоречивом состоянии. Все компилируется, но контракт на обслуживание нарушен. Я определенно предлагаю использовать ChannelFactory, когда это возможно, вы делаете свою жизнь намного легче.

Возможной альтернативой может быть запись prebuild script, которая вызывает утилиту SVCUtil для создания прокси-сервера каждый раз, когда вы создаете свой проект, но в любом случае ChannelFactory гораздо более опрятный и элегантный.