Переопределение типов с помощью импорта веб-службы WSE - PullRequest
0 голосов
/ 07 марта 2011

Рассмотрим следующую структуру проекта Visual Studio

  • ProjectA.csproj
    • AClass.cs
  • ProjectB.csproj
    • Ссылки
      • ProjectA
    • Веб-ссылки
      • AWebService
  • AWebService.csproj
    • Ссылки
      • ProjectA
    • ReturnAClassViaWebService.asmx

Проблема возникает, когда ProjectB добавляет веб-ссылку на AWebService и автоматически генерирует весь прокси-код для доступа к AWebService, включая новую реализацию AClass. Поскольку весь наш другой код должен использовать AClass, определенный в ProjectA, мы вынуждены преобразовать AWebService.AClass, возвращенный из службы, во что-то, что мы можем использовать.

В настоящее время мы рассматриваем два решения, ни одно из которых не является идеальным.

  • Редактирование вручную созданного файла Reference.cs для удаления новых определений AClass
  • Сериализация AWebService.AClass в поток, а затем десериализация в ProjectA.AClass

У кого-нибудь есть лучшие решения? Это кажется достаточно распространенным явлением для других разработчиков.

В идеале мы хотели бы, чтобы прокси-код был сгенерирован в ProjectB для ссылки на ProjectA.AClass, а не для генерации новой реализации.

Нашей средой является VS 2008, использующая .NET 2.0.

Ответы [ 3 ]

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

У меня была та же проблема, которую вы описываете, и я попробовал оба указанных вами варианта, но не был полностью доволен ни одним из них.

Причина, по которой мы оба имеем эту проблему, по крайней мере частично, заключается в том, что решение совместно используемой библиотеки между потребителем и поставщиком веб-службы является нарушением принятых шаблонов и практики дизайн веб-сервисов . Что касается потребителя, то должно быть , чтобы знать интерфейс, опубликованный в WSDL

Тем не менее, если вы готовы принять тесную связь между вашим поставщиком веб-услуг и потребителем веб-услуг, и вы знаете , что ваш текущий клиент никогда не будет заменен другим клиентом (который может не быть в состоянии ссылаться на разделяемую библиотеку), тогда я понимаю, почему предлагаемое решение кажется изящным способом структурировать ваше приложение. ВАЖНОЕ ПРИМЕЧАНИЕ: Можем ли мы действительно честно ответить да на оба этих вопроса? Вероятно, нет.

Подведем итог:

  1. Проблема возникает, когда у вас есть классы (например, строго типизированный набор данных), определенные в некоторой общей библиотеке (используемой как на клиенте, так и на сервере).
  2. Некоторые из ваших общих классов используются в интерфейсе, определенном вашим веб-сервисом.
  3. Когда добавляется веб-ссылка, в пространстве имен веб-ссылки определяются классы прокси (для ваших общих классов).
  4. Из-за различных пространств имен прокси-класс и его фактический аналог в общей библиотеке несовместимы.

Вот четыре решения, которые можно попробовать, если вы хотите продолжить настройку общей библиотеки:

  1. Не. Используйте прокси-класс на стороне клиента. Вот как это должно быть сделано. Он работает нормально, если только вы не хотите одновременно использовать аспекты общей библиотеки, которые не предоставляются веб-службой WSDL.
  2. Реализация или использование предоставленной функции копирования / дублирования класса (например, вы можете попытаться объединить () один строго типизированный набор данных в другой). Преобразование не представляется возможным, и опция копирования, как правило, тоже не очень удачное решение, поскольку она имеет нежелательные побочные эффекты. Например. Когда вы объединяете набор данных в другой, все строки в целевом наборе данных будут помечены как «измененные». Это можно было бы воскресить с помощью AcceptChanges (), но что, если пара полученных строк была фактически изменена.
  3. Сериализация всего - кроме элементарных типов данных - в строки (и обратно на стороне потребителя). Потеря безопасности типов является одной из важных слабостей этого подхода.
  4. Удалите явное объявление общего класса в Reference.cs и уберите пространство имен из общего класса, где бы оно ни упоминалось в Reference.cs. Это, наверное, лучший вариант. Вы получаете то, что вы действительно хотели. Общий класс возвращается веб-сервисом. Единственным раздражающим недостатком этого решения является то, что ваши изменения в файле reference.cs теряются при каждом обновлении веб-ссылки. Поверьте мне: это может быть серьезно раздражает.

Вот ссылка на подобное обсуждение :

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

Вы можете повторно использовать существующие ссылочные типы между клиентом и сервисом, нажав кнопку «Дополнительно» в форме «Добавить ссылку на сервис».Убедитесь, что установлен флажок «Повторное использование типов в ссылочных сборках», и при создании клиента службы он должен повторно использовать все типы из проекта А.

В предыдущих версиях это не всегда работало правильно, и мне пришлосьявным образом выберите сборки общего типа, выбрав параметр «Повторное использование типов в указанных ссылочных сборках», а затем отметив соответствующие сборки в списке.Тем не менее, я только что проверил это с VS 2008 SP1, и он, кажется, работает как ожидалось.Очевидно, что вам нужно убедиться, что типы, которые используются в проектах службы и клиента, относятся к проекту А.

Надеюсь, что это поможет.

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

Мы столкнулись с похожей проблемой в одном из наших проектов. Поскольку у нас было несколько зависимостей, мы в итоге создали циклическую ссылку, поскольку для проекта 1 требовались объекты из проекта 2, но проект 2 не мог быть собран до проекта 3, который основывался на проекте 1.

Чтобы решить эту проблему, мы извлекли все открытые автономные классы из обоих проектов и поместили их в одну библиотеку. В итоге мы создали что-то вроде этого:

  • Framework.Objects
  • Framework.Interface
  • Framework.Implementation
  • WebService

В нашем случае WebService будет связан со всеми проектами, тогда как внешние стороны будут только ссылаться на объекты и классы интерфейса для работы. Фактическая реализация была связана во время выполнения с помощью отражения.

Надеюсь, это поможет

...