На работе стоит задача разработки и прочтения курса по WCF для коллег. В принципе сам курс видится пока вполне стандартным.
Вот примерный план:
Часть 1. Основы создания сервисов и клиентов WCF
- История и альтернативы
- Базовые понятия сервисов
- Пример создание простого сервиса
- Клиенты WCF
- Пример создания клиента к WCF
Часть 2. Подробное изучение возможностей
- Контракты (Service Contracts, Data Contracts)
- Конечные точки (Address, Bindings, настройка транспорта, …)
- Управление экземплярами сервиса (PerCall, PerSession, Singleton, Управление сессией и граничные операции)
- Управление операциями (Request-Reply методы, One-Way методы, Callback методы, Потоковые данные)
- Управление конкурентным выполнением (Single, Reentrant, Multiple, асинхронные операции)
- Хостинг (Self-hosting, IIS, WPA)
- Обработка ошибок
- Метаданные и управление созданием proxy
- Безопасность (Bindings & security, Аутентификация, Защита передачи, Авторизация)
- Очереди и надежные сессии
- Транзакции
- Не-SOAP варианты использования WCF (REST-style программирование для WCF, WCF Syndication, AJAX Integration and JSON Support)
- WCF Discovery (.Net 4.0)
- Routing (.Net 4.0)
Часть 3. Расширение WCF
- Модель расширения WCF
- Extending Encoders and Serializers
- Extending the Metadata System
- Extending Security
- Extending Bindings and Channels
Тут все стандартно (можно, наверное поспорить, что стоит и чего не стоит включать, в каком порядке и т.д., но в общем и целом это не очень принципиально). Зато есть очень большой вопрос, как сторить практику.
С одной стороный, нужны простые задания для закрепления темы. Т.е. чтобы то, что было рассказано на лекции, можно было бы проверить на практике.
С другой, есть множество, не очевидных на первый взгляд, моментов, связанных даже не столько с тонкостями самой технологии (этому просто не возможно научить – во-первых, не осилить, во-вторых, все равно забудется), сколько с приемами разработки/проектирования для данной технологии.
Чтобы было понятно приведу такой пример: стоит задача сделать многозвенное приложение, работающее с некой моделью данных (достаточно разветвленной). Каких-то сложных бизнес-операций не предвидится, ну т.е. они, конечно, есть, но их не так много, в основном чистые CRUD-процедуры.
(Вообще, я уже понял, что из-за исходной ориентации на SOAP, который есть суть удаленный вызов процедур, WCF довольно неважно работает с сервисами управлениями данными)
Сразу возникает вопрос: как строить сервис для доступа (т.е. хотябы только для выборок) к таким данным?
- Делать вручную (или кодогенерацией) специальные методы на кажду возможную операцию: типа GetCustomer, GetAllCustomers, GetCustomerForXXX, …, GetProduct, ….). Нормальный вариант, если сущностей ограниченное количество (и не расширяется),
- Сделать обобщенный CRUD-сервис c набором станадартных методов типа GetEntity, GetAllEntity, GetEntitybyQuery, … Сразу должны появиться вопросы: как поддерживать типизацию (в том числе на стороне клиента), как передавать имя/код сущности с которой планируется работать, …, и т.д.
- …
Ну а далее вопросы сыпятся как из рога изобилия:
- а если хочется иметь удобный доступ к связанным сущностям (а-ля “ленивая загрузка”) как это организовать?
- а если мы хотим иметь произвольные выборки на стороне клиента (например, чтобы сделать полноценное клиентское/интеграционное API) как это организовать? Этакий “удаленный LINQ” (в идеале).
- как быть с операциями сохранения и обновления? Особенно если хочется обновлять и сохранять сразу группы связанных записей? Например, на стороне сервера такие ORM как NHibernate очень неплохо такую задачу решают (у них в сессии хранится полный контекст, который позволяет получить именно изменения + все объекты связаны как надо) – а что делать в распределенной среде?
- как делать пейджинг?
- …
Да, я знаю, что есть WCF Data Services, который отчасти эти проблемы решает. Но именно, что отчасти…
Ну хорошо, вот более простая и насущная задачка: как бороться с проблемой “ломания” клиентских proxy, в случае возникновения ошибки в транспорте? Я до сих пор не знаю стандартного механизма прозрачного переподключения. То ли я тупой, то ли он так глубоко спрятан… Так или иначе, но я точно не один такой – в нескольких известных мне проектах вынуждены были делать обертки над WCF, с целью “рециркуляции” proxy.
В общем, если копнуть слегка в глубь, то реальных проблем и сложностей использования отыщется не мало (впрочем, как и в любой другой технологии). И как обычно, готовых 100%-ых рецептов нет, нужно подбирать решения под потребности…
Собственно хочу понять:
- стоит ли нагружать людей подобными задачами? Скажу сразу, что курс будет довольно растянутый (на месяц, наверное – по паре двухчасовых лекций в неделю), а значит время подумать, поприкидывать варианты, поискать решения будет. Хоть и не много. В любом случае, нужно обязательно разбирать варианты, я думаю.
- если затрагивать такие весьма практические аспекты, то что бы стоило включить? Пару примеров, которые мне кажутся полезными, я привел – это задачи из темы проектирования API для CRUD-сервиса на базе WCF и генерация клиентских proxy. Сюда же можно добавить: API для транспортировки блобов/файлов, использование аспектов (которые будут логировать операции, управлять правами, …) для упрощения кода и удешевления его поддержки. А что еще?
Заранее признателен.
Так может это стоит донести до остальных? Чтобы народ не попадал на те же грабли? Я тоже в SOAP с точки зрения передачи данных разочаровался. Зачем делать Data сервис на технологии, которая не очень хорошо поддерживает работу с данными?
Дай лучше на реализацию какой нибудь несложный, но полноценный пример прикладного сервиса. Самое банальное – банковский сервис:
1. Все базовые знания и так проверишь – без контрактов и правильной конфигурации сервис не запустишь.
2. Можно проверить правильность проектирования сервисов.
3. Можно легко проверить работу с безопасностью.
4. Логирование, аудит, транзации, потоки и пр. тоже ложатся в задание.
5. Данных будет немного и они будут хорошо структурированы.
6. Можно попробовать REST как API для сайта банка.
В общем, мне кажется такое задание гораздо лучше чем исследовать сферического коня для работы с абстрактной моделью данных.
Я бы сказал что не от части, а лучше решает. По сути OData для этого и спроектирован. Есть конечно проблеммы, но их я думаю можно порешать или обойти (в SOAP это бывает порой принципиально невозможно).
Стандартного механизма нет. Тут у вендора позиция простая – правильно проектируй контракты ошибок и будет тебе счастье, ибо проксик не будет переходить в Fault. Есть только стандартный хак – свои проксики и работа с каналом наприямки. При падении проксика канал пересоздается автоматом. Есть только один нехороший недостаток – производительность такого решения не очень хороша. Пересоздание канала штука затратная. Есть еще вариант, если хочется автоматом по WSDL пересоздавать автогенерируемые проксики – сделать проксик над проксиком с помощью какого нибудь AOP движка или самому. Но и в этом случае все по сути сводится к пересозданию канала.
Ну и собственно твои вопросы:
– стоит ли нагружать людей подобными задачами? нет конечно. Если по ходу возникнет потребность – рассказать как решается та или инач конкретная проблемма. А лучше пусть сами попробуют ее решить, благо интернеты кишат решениями.
– если затрагивать такие весьма практические аспекты, то что бы стоило включить? включать стоит то, с чем 100% столкнутся. А тут уже надо смотреть что у тебя в конторе будут за задачки. Если это надежные нагруженные Enterprise системы – одно. Если REST сервисы как API для сайтов – совсем другое. От себя могу добавить – полезной бывает безопасность (хотя штука для восприятия очень сложная), продвинутое конфигурирование и управление клиентскими проксиками, многопотоковая работа (многие реально не понимают зачем локи в PerCall сервисе). Блобы лучше не давать подробно. Реально редко возникают ситуации их использования, а подводных камней так очень много, буквально шаг в сторону и расстрел.
Согласен. Но вопрос: как донести. Если просто рассказать о проблемах, то это, мне кажется не будет воспринято.
Сразу возникает вопрос: а альтернатива? REST (oData)? Ну и вопрос в объемах – пока не надо передавать произвольные списки и выборки, все вполне не плохо работает.
Я похоже не очень хорошо выразился… Собственно, я так и хотел поступить – давать два типа заданий. Одни просто на закрепление того, что рассказывается на лекциях (без изысков – просто чтобы проделать все своими руками).
А вот второй тип заданий (скорее общее сквозное задание). Это разработка полноценного приложения с WCF в качестве транспорта. И вот здеь хотелось бы затронуть побольше вопросов проектирования (может проектирование звучит слишком громко, но суть именно такая). Просто самый, пожалуй распространенный тип приложений, это “клиент к базе данных (с вариантами)”. Когда я впервые взялся за проектирование такого клиента у меня и возникли те вопросы, которые я тут написал.
Поэтому возникла мысль предложить спроектировать/разработать такое “data-ориентированное” приложение.
Общая мысль:
– взять в качестве БД (модель) уже готовую AdwentureWorks
– предложить разработать простейший 3-звенный клиент к такой базе.
– задания выдавать постепенно и сразу или на следующем занятии (чтобы была возможность поразмыслить над вариантами решения) обсуждать как можно решить задачу (т.е. не предлагать решение, а обсудить разные варианты и где они хороши).
Другой вариант – посвятить этому целое занятие где-нибудь в середине, а потом еще одно в конце для подведения итогов. Тогда можно будет предметно обсудить всякие нюансы, т.к. у слушателей уже будет базис – они уже будут знакомы с основами.
Думаю, мы уже выяснили, что мыслим примерно одинаково – что нужно целостное практическое задание).
Я думаю, что ты согласишся, что на простых примерах “для закрепления” довольно сложно понять подходы к использованию (не проблемы и ограничения), а именно подходы к использованию и вызывают проблемы – особенно если ранее использовал только 2-х звенные решения (или даже Web, но с минимум клиентской логики), т.к. решение конкретных программистских вопросов действительно проще найти в Internet.
О! Вот это то, что нужно.
А можешь в паре слов – что именно нужно показать/на чем заострить внимание (с чем может быть сам сталкивался)?
Тогда может хотябы показать на примере – с чем именно возникают сложности. Ну чтобы люди представляли “размер бедствия”.
Приведи пример, когда надо именно передавать большие выборки без пейджинга? Причем пейджинг невизуальный. Если интерфейсно для пользователя будет все прозрачно, а API для разработчика будет оборачивать пейджинг – никто ничего и не заметит. Вспомни chunked запросы. Выглядит как будто передается Stream, а реально работает тот же самый пейджинг данных.Тогда да – OData это решение, причем очень даже неплохое мне кажется.
Про безопасность ты в принципе в курсе. Тут нужна база: безопасность на уровне сообщения и транспорта, в чем отличия (как правило хватает отличий в скорости работы, ограничениях на размер пакета и т.д., то есть все что вытекает из принципов конфеденциальности и целостности на разных уровнях).
Про клиентски проксики – тут надо заострить внимание на таком аспекте, кек правильное проектирование контрактов ошибок: все ошибки которые в контракте не валят клиентский проксик, поэтому они так важны. Если же валится ошибка коммуникаций, то надо пересоздавать канал. По поводу клиентских проксиков – можно просто показать как работать с сервисом без использования автосгенерированного проксика (может быть первые задания сразу начинать не с генерации проксика, а создания канала руками). Дальше ребята сами разберутся.
Многопотоковая работа. Тут народ, который писал под ASP.NET обычно хорошо разбираются, а вот ребята, что писали под Desktop валятся, потому что не понимают что один код будет обрабатывать кучу запросов и специфика будет разная. Причем неправильная работа с многопоточностью ведет к очень трудноуловимым ошибкам (проявляется только при нагрузке или при “стечении обстоятельств”).
Тут нужно понимаение того, как WCF работает внутри. Из простых принципов исходят сложные ситуации и неочевидные моменты. На самом деле можно просто показать ситуацию “security via streaming” и объяснить почему такое происходит.
PS: Скоро тоже буду актуализировать курс по WCF для отдела. Если есть возможность поделиться материалами и/или опытом – буду крайне признателен. У меня правда сроки не такие гигантские как у тебя и больше ориентация будет на самостоятельное изусение, но о подводных камнях всегда лучше знать 🙂
Ну да, согласен. Без пейджинга сложно.
Но я бы зашел с другой стороны – когда в принципе нужно передвать на клиента большие выборки.
Я вижу 2 варианта: для показа списков и для интеграционных задач (типа получить текущую выгрузку). Все, больше ничего не придумывается.
И там и там, в принципе сложность в том, что надо передвать выборки порезанные не только по строкам, но и по столбцам (т.е. передавать проекции с изменяемым набором полей) . Так что уже нужно что-то придумывать. Один из вариантов REST (но и тут вопрос – как принимать объекты), другое – свой велосипед (в этом случае от WCF будет использоваться только сериализация, а все остальное будет свое).