Пара слов о себе — я работаю в компании Incoding Software, которая много лет успешно занимается аутсорсингом, выполняя Internet и Intranet проекты в различных областях ( медицина, доски объявлений, социальные сети и многое другое)
Incoding Framework — это клиент / серверное решение для разработки веб проектов на платформе asp.net mvc.
Состоит из трех частей:
- Серверная — реализация CQRS и Event Broker
- Unit Test Contrib — набор утилит и сценариев для быстрого написания тестов
- Клиентская — делится на:
- IML — Декларативный язык ( Incoding Meta Language ), позволяющий описывать клиентские сценарии на C#
- Model View Dispatcher ( MVD ) — CQRS на MVC, позволяет исполнять Command и Query без написания промежуточных Controller
примечание: особенность Incoding Framework в том, что каждая часть интегрируется между собой ( IML использует MVD для AJAX, MVD исполняет CQRS и т.д ), но позволяет применять по отдельности ( на Nuget 3 независимых пакета )
Так как рассмотреть каждую часть framework в одной статье не получится, то будет сделан акцент на самом интересном компоненте нашей библиотеки — это IML. Почему я выделил именно клиентскую часть, дело в том, что CQRS, Event Broker и Unit Test имеют множество аналогов в “мире” .net и быстро заинтересовать ( хотя мы имеем ряд особенностей ) крайне трудно, но IML это инструмент, который пока не имеет прямых аналогов.
Не имеет аналогов, то как решаются задачи ?
У IML нету прямых аналогов, но конечно есть косвенные:
- JavaScript
- Jquery
- AngularJS, Backbone, Marionette
- TypeScript
Без JavaScript, не построить веб сайт
Вам приходится бороться со всеми сложностями:
- Ошибки только в runtime
- Динамическая составляющая языка, которая становится проблемой в больших приложениях
- Оказывается null бывает разный ( null, undefined, 'undefined' )
- И многие другие “прелести” нетипизированных языков
Не слышал, у меня же Jquery
С появлением Jquery разработка веб приложений стала проще, но с ростом сложности приложений на клиентской стороне скриптовый подход к написанию кода стал не оправдан из-за возрастающего уровня дубляжа, а такие «особенности» JavaScript, как глобальные функции и переменные ещё больше усложняют поддержку крупных проектов.
Хорошо, построим архитектуру на UI
Архитектура MVVM или MVС, построенная на JS, обеспечивает коммуникацию с сервером, но когда на стороне клиента появляется своя модель, то приходится её синхронизировать с той, что на серверной стороне и это разделяет разработчиков на front end и back end.
примечание: идея разделения программистов на серверных и клиентских, кажется крайне неудачной, потому что приходится согласовывать их действия и всегда, кто-то работает быстрее, а кто-то медленнее, но если этого не делать, то разработчик должен знать особенности разработки на каждой стороне.
Чтобы не строить архитектуру с нуля, можно воспользоватся готовыми JavaScript framework, например AngularJS, но тогда, Вам надо писать Controller, Routes и многое другое, повторяя уже существующий код на asp.net mvc.Главная проблема, всех javascript framework, это то, что Вам надо писать JS код
О, а если без JS
В последние время развивается тенденция написания JavaScript, используя типизированный интерпретатор или альтернативный язык
TypeScript — это возможность писать JavaScript, но в C# подобном синтаксисе. В чем тогда отличие TypeScript от IML:
- не имеет готовых функций ( IML это декларативный язык, который описывает поведение, но не реализацию )
- надо учить новый язык ( IML это C# )
- надо устанавливать дополнительных утилит для формирования результирующего JS ( IML это C# )
- не имеет интеграции с серверной частью ( IML адаптирован под asp.net mvc )
Ладно, чем же поможет IML?
IML предлагает набор методов для написания любых клиентских сценариев без JavaScript кода. Браузер работает по принципу событийной модели, и как показала практика, вариантов сценариев не так много.
Давайте рассмотрим стандартный алгоритм:
- Возбуждается событие у DOM элемента ( от имени пользователя или программным путем )
- Выполняется Action ( чаще всего это Ajax-запрос на указанный url )
- Обратный вызов по завершению Action, который запускает цепочку действий ( вставка полученных данных, работа с DOM, обновление CSS, применение JQuery plugin )
Покажи код, сразу все ясно будет
Html.When(JqueryBind.InitIncoding)
.Do()
.AjaxGet(Url.Dispatcher().Query(GetCardsQuery { Client = Html.Selector.Name(r=>r.Client) }))
.OnSuccess(dsl => dsl.Self().Core().Insert.WithTemplate(idTemplate.ToId()).Html())
.AsHtmlAttributes()
.ToDiv()
Лучше алгоритм
IML язык декларативный, поэтому его конструкции легко можно описать
- When InitIncoding — когда наступит событие появление элемента на странице
- Do — способ обработки поведения события ( Prevent Default, Stop Propagation )
- Action — ajax запрос на указанный url
примечание: на примере для построения url применяется MVD, но можно и по старинке Url.Action(«controller»,«action», new { Client = Html.Selector.Name(r=>r.Client) })
- On — при удачном завершении Action, выполняем последовательность действий, на примере это вставка данных через template
- AsHtmlAttributes — упаковываем наш IML код в «теплый и надежный» RouteValueDictionary
- ToDiv — объявляем на странице, как Div ( можно в любой tag )
Проще всего по структурной схеме разобраться
Какие доводы ещё в пользу IML?
Если выделить основные преимущества IML, то:
- No JS — эта фича является самой ключевой, потому что именно она выделяет IML на фоне других решений
- Типизация — это эффект от первого пункта, Вам не надо больше изучать замыкания JS, думать что за «var» тут или сколько аргументов передать в function
- Стандарт — декларативный язык на много проще использовать в команде
- JSON ( Rest api ) и клиентские template — многие решения умеют работать в такой связке, но Incoding Framework имеет все средства из «коробки»
Вот, говорите у нас C#
Язык C# обладает, наверно, самым богатым функционалом и важно то, что все это можно использовать в рамках Вашей Razor страницы, то есть анонимные функции, лямбда и многое другое, что позволяет проводить рефакторинг Вашего приложения.
- возможность разрабатывать свои Html extensions, которые потом повторно использовать на разных страниц.
@Html.Project().Load(setting => { setting.Template = Selector.Jquery.Id(tmplId); setting.Url = Url.Dispatcher().Query(GetCardsQuery { Client = Html.Selector.Name(r=>r.Client) }); })})
примечание: код выполняет туже задачу, что была рассмотренная в первом примере
- анонимные функции для построения MvcHtmlString, прямо во View
@{ Func<bool, mvchtmlstring=""> createComplete = (value) => Html.When(JqueryBind.Change) .Do() .AjaxPost(Url.Dispatcher().Push(new SomeCommand { IsAdmission = each.For(r => r.IsAdmissionComplete) })) .OnSuccess(dsl => // something ) .AsHtmlAttributes() .ToCheckBox(value); } @using (each.Is(r => r.IsComplete)) { @createComplete(true) } @using (each.Not(r => r.IsComplete)) { @createComplete(false) }
Прямо таки все хорошо?
Приведу список отрицательных моментов Incoding Framework
- Небольшое сообщество — для open source проектов, очень важно иметь единомышленников, но пока инструмент применяется в рамках
нашей компании и несколькими знакомыми командами - Надо изучать — мы движемся в сторону уменьшения материалов, которые надо изучить для продуктивного использования Incoding Framework, но инструмент покрывает весь цикл разработки
- Документация — за прошлый год было выложено 2 проекта на open source и опубликовано 20 постов в блоге, но пока ещё не все детали освещены
Заключение
В начале я написал, что наша компания занимается разными проектами, я подчеркнул, что круг решаемых задач, который стоит перед Incoding Framework очень большой. Многие скажут, что практически каждая фирма разрабатывает для себя свой framework, но мне кажется у нас получился инструмент, который может быть использован и другими командами.
P.S. Рад услышать отзывы и замечания