2009-12-11 2 views
6

У меня есть приложение WPF, которое до сих пор было только клиентом, но теперь я работаю над его разбиением на клиентскую и серверную стороны. В этой работе я представляю WCF для взаимодействия клиент-сервер. Мое приложение имеет несколько проектов, и ссылки на службы необходимы из более чем одного из них.Структура приложения с использованием WCF

Первоначальное усилие при проведении разделения состоит в том, чтобы делать все «прямо вперед». Все проекты, требующие связи с сервисом, получают ссылку на службу, а также основной проект приложения WPF - для получения там app.config. Я считаю, что это превращается в беспорядок довольно быстро, и я не могу себе представить, что это типичная архитектура, которую люди используют? Я также видел проблемы с тем, что каждая из ссылок на службы генерирует новую реализацию классов DataContract, поэтому нет общего понимания классов DataContract при перекрестке проектов. У меня есть несколько классов ViewModel в одном проекте, а другой проект инициирует некоторый ViewModel. Я хотел бы передать объект, полученный из службы, но я не могу, поскольку генерируемое клиентское представление полученного объекта отличается в каждом проекте.

Итак - существует ли рекомендованный способ структурирования таких разделов клиент/сервер с использованием WCF? Или принципы следовать? Я думаю, что один общий прокси-проект, используемый на стороне клиента, который выполняет связь с сервисами, обертывает полученные данные и возвращает данные в форме, хорошо известной клиентским библиотекам. Должен указывать только одну служебную ссылку, и я думаю, мне нужен только App.config в проекте wpfApp? Имеет ли это смысл?

ответ

16

Я хотел бы структурировать мою WCF решение, как это:

контрактов (класс библиотека)
Содержат все контракты службы, операции, неисправностей и данных.Может быть разделена между сервером и клиентом в чистом сценарии .NET-на-.NET

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

служба хост (ы) (опционально - может быть Winforms, консоль App, NT Service)
Содержит службы хост (ы) для отладки/тестирования, или, возможно, также для производства.

Это в основном дает мне серверную сторону вещей.

На стороне клиента:

Клиентские прокси (класс библиотеки)
Я хотел, чтобы упаковать мой клиент прокси в отдельную библиотеку классов, так что они могут быть повторно использованы несколькими реальными приложениями клиента. Это можно сделать с помощью svcutil или «Добавить служебную ссылку» и вручную настроить получаемые ужасные app.config или выполнить ручную реализацию клиентских прокси (при совместном использовании сборки контрактов) с использованием конструкций ClientBase<T> или ChannelFactory<T>.

1-п фактические клиенты (любой типа приложения)
обычно только ссылаются на сборке клиента прокси-серверах, или, возможно, сборка контрактов тоже, если это общий доступ. Это могут быть ASP.NET, WPF, Winforms, консольное приложение, другие сервисы - вы называете это.

В пути; У меня красивый и чистый макет, я использую его последовательно снова и снова, и я действительно думаю, что это упростило мой код и упростило его работу.

Это было вдохновлено Extreme WCF screen cast Мигелем Кастро на DotNet Rocks TV с Карлом Франклин - настоятельно рекомендуется снимать экран!

+0

Спасибо за очень хороший ответ!Несколько вопросов назад: имея хост службы, вам нужно запустить как хост, так и клиент при запуске приложения? Или есть какой-то способ обойти это? Что касается клиентских прокси - что бы вы предпочли? Manual impl звучит более согласованно, так как вам не нужно иметь дело с отзывами об обслуживании. – stiank81

+0

@bambuska: конечно, вам нужно запустить как хост службы, так и клиент для тестирования; выберите «запустить несколько проектов» в Visual Studio для достижения этого - вы можете запустить как хост службы, так и клиент при нажатии F5. –

+1

Прокси клиентов: Мне нравится полный контроль, который у меня есть, когда я выполняю ручную реализацию клиентских прокси - это ** требует **, хотя я могу разделить контракт между сервером и клиентом (так как ручное импровизация клиентских прокси должно иметь доступ к фактическим контрактам) –

1

Это зависит. WCF - это большая структура, и она предназначена для охвата множества различных сценариев.

Но для непосредственного применения, как у вас, когда вы не заботитесь о вещах, как Java или общего-взаимодействии веб-службе Interop, это то, что я делаю:

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

Таким образом, вы, кажется, делаете что-то вроде права. То, что вам, вероятно, НЕ нужно, это автоматическое создание прокси-серверов вообще. Это просто причиняет вам боль. Поэтому не используйте диалоговое окно Add Service Reference для того, что вы делаете. Просто включите свои общие сборки DataContract и используйте ChannelFactory для получения прокси-сервера для вашего интерфейса службы, определенного в общей библиотеке. Это также не позволяет вам повторно генерировать прокси-сервер в Visual Studio, который для любого проекта с приличным размером стареет ОЧЕНЬ БЫСТРО.

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

+0

Спасибо! Это звучит очень привлекательно. Автогенерированные прокси действительно причинили боль уже ... Я на самом деле пытаюсь выполнить аналогичную реализацию с той, которую вы уже описали, но она прекратилась, когда мне нужны асинхронные службы. Могу ли я легко использовать ChannelFactory для создания асинхронных сервисов? – stiank81

+0

О, и JavaInterop и т. Д. Совсем не имеет отношения. Это будет все .net для .net! Имея DataContracts в общей библиотеке, я действительно могу вернуться, например. объект MyClass из службы, и он будет получать тот же самый тип? – stiank81

+0

Да: http://msdn.microsoft.com/en-us/library/bb885132.aspx –

1

Обычная структура я использую:

Common - содержит интерфейсы, данные-контракты, контракты на обслуживание, абстрактные классы и т.д.; Клиент - ссылки Common, содержит серверный прокси-класс; Сервер - ссылки Общие, содержит фактические классы реализации;

+1

Согласовано. Хотя я часто делал бы общую библиотеку, это DTO, которая может использоваться с обеих сторон службы, а затем не использовать сгенерированные классы прокси. – asgerhallas

+0

Похоже, мне нужен общий проект для общего материала ..! Используете ли вы автогенерированные прокси-серверы или опускаете их - например, @asgerhallas? Конечно, я бы хотел опустить их, если смогу. Они уже вызвали слишком много боли. – stiank81

+1

Я получаю прокси-класс от ClientBase и реализую интерфейс для переадресации вызовов на канал. – Goran

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