ASP.NET MVC използва WCF

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

Искам да разреша на потребителски интерфейс на трета страна да осъществява достъп до тези сервизни обекти чрез WCF.

Хрумна ми, че преобразуването на моя съществуващ слой на услугата в уеб услуги или дори добавянето на нов слой на уеб услугата между потребителския интерфейс и съществуващия слой на услугата ще наруши моите модулни тестове, освен ако не намеря начин да преодолея тази празнина.

Опитвах се да намеря решение, при което моят потребителски интерфейс беше кодиран спрямо интерфейс на сервизния слой (той вече е) и можех да използвам DI, за да предам изпълнението на уеб услугата по време на изпълнение и да предам съществуващото изпълнение по време на тестване на единица. Внедряването на уеб услугата просто ще извика съществуващото изпълнение.

Въпроси:

  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 проекти, което може да бъде малко пресилено за повечето магазини. Например, не виждам много магазини, които споделят договори за данни между проекти. Да, в един перфектен свят вероятно трябва да споделяте много OS типове (като адрес) в проекти, но не го виждам да се прави много често. Така че, склонен съм да поставя всичките си договорни неща в един VS проект.

person Don Demsak    schedule 22.12.2010

Ако вашите услуги вече са дефинирани като интерфейси, тогава имате преднина.

Предайте услугите в контролерите като зависимости на конструктора, а не като хранилища. Нека вашият DI контейнер A) предоставя хранилищата на услугите и B) предоставя услугите на контролерите.

Ако искате да поддържате вашия сервизен слой като wcf услуги за достъп от други приложения, ще искате да използвате wcf service factory, за да изтеглите конкретните реализации на услугата от вашия DI контейнер. Ето пример с Windsor, би трябвало лесно да се адаптира към какъвто и контейнер да използвате.

На този етап можете да промените уебсайта си така, че A) да продължите да извиквате услугите директно или B) да ги накарате да се обаждат обратно на уеб услугите, използвайки клиенти на услугата. Има плюсове и минуси и на двата метода.

person Brook    schedule 22.12.2010