ASP.NET MVC, использующий WCF

Мои контроллеры ASP.NET MVC 2 в настоящее время создают объекты службы в своих конструкторах, передавая экземпляры репозитория, созданные Castle Windsor. У меня есть модульные тесты, которые вызывают действия контроллера после передачи экземпляров репозиториев Moq конструктору контроллера.

Я хочу разрешить стороннему пользовательскому интерфейсу получать доступ к этим объектам службы через WCF.

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

Я пытался разработать решение, в котором мой пользовательский интерфейс был закодирован в соответствии с интерфейсом сервисного уровня (это уже есть), и я мог использовать DI для передачи реализации веб-службы во время выполнения и передачи существующей реализации во время модульного тестирования. Внедрение Web-сервиса будет просто вызывать существующую реализацию.

Вопросы:

  1. Целесообразен/возможен ли такой подход?
  2. Есть ли примеры этого в учебнике или проекте с открытым исходным кодом?

ИЗМЕНИТЬ:

Я считаю, что теперь у меня есть работоспособное решение благодаря приведенным ниже предложениям. Я создал приложение службы WCF, которое использует существующие интерфейсы службы из моей модели предметной области. Реализация WCF — это класс, в котором конструктор берет экземпляры репозитория из Ninject в расширение WCF и создает экземпляр службы из модели предметной области. Каждый метод/функция в WCF просто вызывает один и тот же метод/функцию из существующего сервисного уровня.

Были некоторые предостережения. Например, я больше не могу передавать ссылку на мой ASP.NET MVC ModelState при создании службы в контроллере (на самом деле я использую Ninject для создания экземпляра службы WCF и предоставления его конструктору контроллера). Причина в том, что WCF является платформой обмена сообщениями - изменения должны быть явно переданы обратно при каждом вызове (т.е. мои ошибки проверки теперь передаются обратно как ссылочные параметры для отдельных функций/методов).

Мне также пришлось добавить некоторые ссылки на сериализацию/модель обслуживания в мой бывший проект POCO Core.

Кроме того, я переключился с Castle на Ninject, потому что WCF-решение Castle низкий уровень зрелости, и мне было неудобно использовать это в то время.


person Mayo    schedule 22.12.2010    source источник


Ответы (3)


Можете ли вы объяснить более подробно, почему ваши тесты ломаются?

Я постоянно занимаюсь этим видом разработки. Сервисы как классы => сервисы как сервисы WCF.

Ваши тесты не должны ломаться. Служба WCF — это почти 100% контракт, базовый бизнес-код и логика не должны изменяться.

person John Farrell    schedule 22.12.2010
comment
Я предполагал, что это просто невозможно, но я попробую и посмотрю, как это работает. Вы буквально размещаете свою службу WCF и запускаете свои модульные тесты для размещенной службы? - person Mayo; 22.12.2010
comment
Нет, я просто запускаю его для экземпляра объекта new MayosService(). - person John Farrell; 22.12.2010
comment
Это просто щелкнуло... это просто класс, реализующий интерфейс. - person Mayo; 23.12.2010
comment
Все ответы здесь были полезными - я просто посчитал, что ваши ответы оказали наибольшее влияние на мой подход. Спасибо! - person Mayo; 28.12.2010

Ознакомьтесь с Фабрикой программного обеспечения веб-сервисов, созданной командой Patterns & Practices. Это хороший способ структурировать ваши услуги в контрактные проекты (данные, сообщения, услуги) и «бизнес-код». Как только вы лучше поймете, как структурировать свой код, вы можете реорганизовать их стиль так, чтобы он вам больше подходил. Их пример имеет тенденцию разделять все на множество проектов VS, что может быть немного излишним для большинства магазинов. Например, я не вижу, чтобы многие магазины обменивались контрактами данных между проектами. Да, в идеальном мире вам, вероятно, следует совместно использовать много типов ОС (например, адрес) между проектами, но я не вижу, чтобы это делалось очень часто. Итак, я обычно помещаю все свои контракты в один проект VS.

person Don Demsak    schedule 22.12.2010

Если ваши сервисы уже определены как интерфейсы, то у вас есть преимущество.

Передайте службы в контроллеры как зависимости конструктора, а не репозитории. Пусть ваш DI-контейнер A) предоставляет репозитории службам и B) предоставляет услуги контроллерам.

Если вы хотите настроить свой сервисный уровень как сервисы wcf для доступа к другим приложениям, вам нужно использовать фабрику сервисов wcf для извлечения конкретных реализаций сервисов из контейнера DI. Вот пример с Windsor, его должно быть легко адаптировать к любой контейнер, который вы используете.

На этом этапе вы можете изменить свой веб-сайт, чтобы либо А) продолжать вызывать службы напрямую, либо Б) заставить их вызывать веб-службы с помощью клиентов служб. У обоих методов есть плюсы и минусы.

person Brook    schedule 22.12.2010