Лирическое вступление
Написать одну хорошую строчку кода, в общем-то, легко: она понятна, делает то, что нужно, ее легко прочитать и понять (если это не строчка на Perl). Когда строчек много, ситуация радикально изменяется в худшую сторону: реальность такова, что проектный код обычно пишется в условиях жестких временных ограничений далеко не клонами Джона Скита, и вместо хорошего кода «маємо те, що маємо». Другими словами, проектный код — это боль. Чем его меньше, тем лучше.
Мы используем фреймворки, чтобы создавать надежные архитектурные и инфраструктурные решения и не писать лишний код в проекте («велосипеды»). Мы используем компоненты, чтобы получить требуемую функциональность через сборку вместо написания одноразовой проектной реализации «с нуля».
Повторное использование кода — это серебряная пуля в борьбе с проблемой увеличения его количества. Мы используем полный арсенал (OOP, FP, CBD, TDD, DDD, MDD и т.д.) для организации кода таким образом, чтобы уменьшить количество кода, избежать дублирования и обеспечить те или иные его характеристики.
В этой статье я хочу рассказать про новый инструмент для организации эффективного повторного использования артефактов как в рамках одного проекта, так и между разными проектами. Инструмент называется NReco (для платформы .NET), и с его помощью можно:
— генерировать прототипы веб-приложений за несколько минут;
— быстро разрабатывать полнофункциональные бизнес-приложения и админки с написанием минимума проектного кода (до х10 раз быстрее, по сравнению c классической разработкой на WebForms/MVC);
— увеличить степень повторного использования как внутри проектов, так и между разными проектами в одной организации (уменьшение издержек = профит);
— радикально уменьшить затраты и улучшить качество при разработке проектов через организацию продуктовой линии с помощью фабрики программ (software factory).
NReco — это .NET проект с открытым исходным кодом, и он полностью бесплатен для коммерческого использования.
Немного истории
В далеком 2006 году мы в NewtonIdeas разрабатывали достаточно сложное BPM-решение для управления процессами аудитов в области обеспечения качества.
Согласно традиции, имелся в наличии
Уже тогда мы использовали Spring-подобный IoC-контейнер собственного производства, поскольку подходящего контейнера с
С UI была вообще беда: вырастали ASCX-шаблоны размером 60kb и больше, где размножались вложенные Repeater-ы и причудливо работающие databinding-выражения. Чтобы внести минимальное изменение, требовалось вдумчивое изучение всей этой колбасы, и это в итоге занимало неприличное количество времени у разработчиков.
У меня был хороший опыт использования XSLT (в начале
В 2008 часть наработок были открыты в виде open-source проекта Open NIC.NET (инфраструктурные компоненты), а все, что касалось MDD, было написано с чистого листа и названо NReco.
Разделение условное и просто сложилось исторически: на самом деле оба проекта развивались синхронно, как единое целое. Эта первая версия использовалась (и развивалась) для разработки десятков веб-проектов
В результате тотального рефакторинга и переосмысления накопленных наработок появилась полностью новая версия NReco 2.0, которая, я надеюсь, достойна внимания широкой аудитории.
Генерация NReco-приложения
При проектировании NReco 2.0 я старался максимально использовать существующую инфраструктуру VisualStudio. Например, при редактировании
XDT. Инфраструктурные компоненты, такие как IoC-контейнер или DALC, являются полностью автономными и могут быть использованы в любом .NET проекте.
Начать знакомство с NReco можно одним из
— Клонировать Git-репозиторий code.google.com/p/nreco (бранч nreco2) и запустить несколько примеров
— Сгенерировать готовое ASP.NET приложениев виде NuGet-пакета.
Дополнительную информацию можно обнаружить на сайте nrecosite.com. Рассчитывать на полноценную документацию пока не приходится: может быть, у меня появится свободное время (ага, а курс снова будет 8грн), или, может, появятся новые контрибьюторы, или что-то еще. С другой стороны, благодаря наличию
Рассмотрим процесс генерации ASP.NET как наиболее эффектный. Допустим, нам нужен прототип для гипотетической мини-CRM с контактами клиентов и сопутствующими справочниками. Чтобы не усложнять процесс настройкой базы, изменим БД на SQLite:
Общие настройки позволяют сразу подключить необходимые пакеты и конфигурацию для фич, которые потребуются в проекте (при необходимости, их можно доставить и позже).
Далее расположен конструктор для определения схемы данных и CRUD-интерфейса. Определим таблицы для справочников:
Для таблиц-справочников CRUD Type выберем Editable List, чтобы удобно было набить значения прямо в списке.
Также добавим таблицу с клиентами, которая будет использовать определенные выше справочники:
Генерация приложения — это тоже трансформация
Установка сгенерированного пакета не должна вызвать особых трудностей: после генерации отображается подробная пошаговая инструкция. В целях тестирования проще всего создать в VisualStudio 2013 (Express for Web подойдет) новый ASP.NET Application Project с шаблоном Empty и core references для WebForms, и сразу установить только что скачанный NuGet-пакет (момент: VS Update 2 должен быть установлен, иначе при установке пакета вывалится ошибка).
Если все прошло успешно, можно запустить приложение нажатием F5, при первом запуске приложение само создаст файл с SQLite базой и инициализирует ее схему. В результате должна отобразиться логин-страница:
В базе по умолчанию создана учетная запись «admin» с паролем «1». После входа наполняем справочники:
И создаем запись для клиента:
Список клиентов, страница с деталями и редактированием прилагаются.
Собственно, это и есть обещанный (абсолютно работоспособный) прототип, который можно получить за несколько минут.
Все артефакты представлены в виде
После изменения
Этот Task ожидает, что у каждого файла с config/dsm/data-schema.dsm.config
(которая включает измененный файл clients.xml
через XInclude) эта инструкция выглядит так:
<?xml-stylesheet type="text/xsl" href="../xsl/model-data-schema.xsl" output-file="../common/_generated_data-schema.xml.config"?>
Нестандартный атрибут этой PI output-file используется для указания имени файла, где должен быть сохранен результат трансформации. Сразу отмечу, что в результатом трансформации может быть и множество файлов (например для модели config/dsm/layouts.dsm.config
).
Бинго! Этого достаточно, чтобы указать, какие
Конечно, считать XSL полноценным языком трансформаций можно только для преобразований XML → XML, однако в случае ASP.NET-приложения этого вполне достаточно: конфигурация IoC-контейнера описывается с помощью XML, а UI-шаблоны (ASPX/ASCX) описываются
Основная магия происходит в XSL-правилах и компонентах, композиция которых приводит к появлению требуемой функциональности.
Под капотом NReco осталось еще много интересного: механизмы связывания с использованием функциональных зависимостей, автоматическое согласование типов (и делегатов!), событийно-ориентированная организация логики приложения и всякое такое. В этой вводной статье нет возможности раскрыть все технические детали фреймворка, который создавался много лет. Но я надеюсь, что изложенного материала достаточно, чтобы вызвать интерес к проекту NReco; особо стойкие могут продолжить знакомство с инструментом через изучение исходных кодов и примеров/тестов, а также просто экспериментируя.
Возможности
Список того, что можно сделать с
— можно задавать произвольные конфигурации рендеринга (в несколько колонок, в табах и т.д.);
— к спискам можно определять фильтры, в том числе достаточно сложные (условия на несколько полей с AND/OR);
— использовать массовые операции в списках;
— использовать произвольные UserControl-ы для рендеринга кастомных элементов или редакторов полей;
— декларативно описывать зависимости между редакторами на формах (классика жанра, 2 зависимых дропдауна, в таком духе);
— определять новые элементы в
— отображать в виде диалогов, абстрактные формы (не привязанные к какой-то таблице; например, для бизнес-действий);
— задавать произвольные SQL-view для использования в провайдерах данных и UI;
— централизовано ограничивать доступ к данным на уровне SQL запросов;
— включить встроенную реализацию отслеживания изменений данных в БД (change data capture / change data tracking).
Этот минимальный набор фичей уже позволяет использовать NReco для быстрого построения админок и разнообразных бизнес-приложений (как минимум, их прототипов). В дальнейшем список доступных
Помимо готовых моделей для описания слоя данных и UI, можно воспользоваться инфраструктурой NReco для определения своих
Вместо заключения
Мне кажется, разработка в аутсорсинге наиболее брутальная. Временные и бюджетные ограничения всегда на первом месте, и любой новый подход проходит жесткую аппробацию реальностью и экономической целесообразностью. Каждый по-своему, но мы все таки используем объектно-ориентированный и компонент-ориентированный подходы в ежедневной разработке. С модель-ориентированной разработкой (MDD) как-то не сложилось — видимо, всё дело в реализации.
Технология NReco сформировалась и выжила в суровых условиях украинского аутсорсинга (более того, в небольшойкоманде, где каждый человек на счету); она не претендует на фундаментальность (как например, MDA от OMG), но при этом позволяет получить выгоды от использования подхода MDD в совершенно обычных веб-проектах уже сейчас, с минимальными затратами на внедрение и обучение.