Комментарии 5
итого:
Задача
Избавить прикладных разработчиков от необходимости написания контроллеров, проекций и сервисов.
а потом:
По шагам
Добавляем SomeEntity: IEntity
Добавляем SomeEntityListDto
Регистрируем маппинг SomeEntity -> SomeEntityListDto
Автоматом получаем метод /SomeEntity/List
Дописываем бизнес-логику в SomeEntityListOperation<SomeEntity, SomeEntityListDto>
Метод /SomeEntity/List начинает использовать новую реализацию с «правильной» бизнес-логикой
возникает вопрос — зачем такая сложность (accidental complexity)?
SomeEntityListOperation — абстракция от WebApi контроллера:
- url операции может быть объявлен через аттрибут
- задачу DI зависимостей в контроллер уже как бы решили
- автоматом получаем content negotiation
- нет необходимости внедрения костылей при требовании кэширования и т.п.: ETag, Expiration, HEAD request etc.
- авторизация тоже поддерживается и настраивается по разным операциям
- нет необходимости сканировать все типы сборки(ок)
Касательно компонентов в других сборках — уже также есть довольно популярное решение: middleware (например, специфиципровано в owin и реализовано в katana и, кстати, поддерживает WebApi). Само использование таких компонентов позволяем избавиться от дополнительных зависимостей между ними в приложении (разве что фрэймворк которых и так идет "из коробки").
Есть еще много причин, почему я не хочу хранить бизнес-логику в теле методов контроллеров (пусть и WebApi), но это очень длинная тема и я не хочу ее развивать.
CQRS как архитектурный паттерн — это в первую очередь про абстрагирование бизнес-логики от инфраструктурного слоя и структурирование кода
с чего вы это взяли? [http://martinfowler.com/bliki/CQRS.html]
Операции (комманды и квейри) могут быть выполнены за пределами WebApi (WCF, ServiceStack, Akka.NET,...) и Web-контекста в целом (например, отправлены в очередь).
могут, но в момент написания кода мы уже знаем контекст в котором будем выполнять команду или запрос. и код будет сильно отличаться в зависимости от контекста:
- для HTTP (WebApi. NancyFX, ServiceStack...) всегда можно использовать специфичные техники (ETag, client cache...)
- для actor-framework (akka, orleans), это специфичный только там код
- WCF — с моей точки зрения отдельная тема (я бы не использовал технологию, пока не прийдется — например, интеграция с особенными протоколами)
- Service Bus — как и с перечисленным выше, это такой же контекст, архитектурное решения, которое влияет на весь остальной код
Есть еще много причин, почему я не хочу хранить бизнес-логику в теле методов контроллеров (пусть и WebApi), но это очень длинная тема и я не хочу ее развивать.
никто не может запретить вам этого. я веду к тому что контекст — важная часть при принятии архитектурных решений от которой никуда не деться. не нравиться хранить код в завязанных на фрэймворк классах — выделите в отдельный чистый и вызывайте оттуда (хотя мое правило — только при необходимисти, как переиспользование функционала либо когда у кода разная ответственность). а излишние абстракции только усложняют код и вносят ограничения на реализацию возможностей инфраструктуры.
кстати, немного по теме DDD, SQRS, ES. есть англоязычная чат группа на slack, в основном так люди с бэкграундом .net. довольно многие если что ответят/подскажут.
началось так: https://twitter.com/randompunter/status/681830829203533824
(хотя мое правило — только при необходимисти, как переиспользование функционала либо когда у кода разная ответственность). а излишние абстракции только усложняют код и вносят ограничения на реализацию возможностей инфраструктуры.
Этот подход хорошо работает в продуктовой разработке, когда вы работаете долго только со своей кодовой базой. Мы работаем в аутсорсе, часто с кодовой базой сомнительного качества. Если есть IOC, мы просто вставляем свой repair-toolkit и начинаем постепенно, вместе с разработкой новых фич, вырезать плохо-пахнущие участки. В этом случае абстрагирование фасадом от внешней инфраструктуры нам помогает. Каков поп, таков и приход, не находите?
Немного особой контейнерной магии