Quantcast
Channel: Найцікавіше на DOU
Viewing all articles
Browse latest Browse all 8115

Быстрая веб-разработка с NReco

$
0
0

Лирическое вступление

Написать одну хорошую строчку кода, в общем-то, легко: она понятна, делает то, что нужно, ее легко прочитать и понять (если это не строчка на Perl). Когда строчек много, ситуация радикально изменяется в худшую сторону: реальность такова, что проектный код обычно пишется в условиях жестких временных ограничений далеко не клонами Джона Скита, и вместо хорошего кода «маємо те, що маємо». Другими словами, проектный код — это боль. Чем его меньше, тем лучше.

Мы используем фреймворки, чтобы создавать надежные архитектурные и инфраструктурные решения и не писать лишний код в проекте («велосипеды»). Мы используем компоненты, чтобы получить требуемую функциональность через сборку вместо написания одноразовой проектной реализации «с нуля».

Повторное использование кода — это серебряная пуля в борьбе с проблемой увеличения его количества. Мы используем полный арсенал (OOP, FP, CBD, TDD, DDD, MDD и т.д.) для организации кода таким образом, чтобы уменьшить количество кода, избежать дублирования и обеспечить те или иные его характеристики.

В этой статье я хочу рассказать про новый инструмент для организации эффективного повторного использования артефактов как в рамках одного проекта, так и между разными проектами. Инструмент называется NReco (для платформы .NET), и с его помощью можно:
— генерировать прототипы веб-приложений за несколько минут;
— быстро разрабатывать полнофункциональные бизнес-приложения и админки с написанием минимума проектного кода (до х10 раз быстрее, по сравнению c классической разработкой на WebForms/MVC);
— увеличить степень повторного использования как внутри проектов, так и между разными проектами в одной организации (уменьшение издержек = профит);
— радикально уменьшить затраты и улучшить качество при разработке проектов через организацию продуктовой линии с помощью фабрики программ (software factory).

NReco — это .NET проект с открытым исходным кодом, и он полностью бесплатен для коммерческого использования.

Немного истории


В далеком 2006 году мы в NewtonIdeas разрабатывали достаточно сложное BPM-решение для управления процессами аудитов в области обеспечения качества.

Согласно традиции, имелся в наличии 23-летнийсеньор (я) и команда со скромным опытом .NET и ASP.NET WebForms в частности.
Уже тогда мы использовали Spring-подобный IoC-контейнер собственного производства, поскольку подходящего контейнера с XML-конфигурациейтогда не было (Spring.NETпоявился позже). Инверсия управления помогала в некоторой степени уменьшить связность проектного кода и обеспечить подобие порядка на уровнях слоя данных и бизнес-логики, правда, при этом растущие объемы XML-конфигурациикомпонентов сами по себе становились проблемой.

С UI была вообще беда: вырастали ASCX-шаблоны размером 60kb и больше, где размножались вложенные Repeater-ы и причудливо работающие databinding-выражения. Чтобы внести минимальное изменение, требовалось вдумчивое изучение всей этой колбасы, и это в итоге занимало неприличное количество времени у разработчиков.

У меня был хороший опыт использования XSLT (в начале 2000-хбыла мода генерировать HTML-страницы с помощью XSLT на сервере), и возникла мысль использовать проверенные инструменты для организации максимально легкого процесса создания моделей и описания их трансформаций. Что может быть проще описания модели в виде XML, ее мета-модели в виде XSD и трансформации в виде XSL? Мы смогли описывать бизнес логику декларативно в виде простых XML-файлови генерировали реализацию в виде композиции специальных компонентов, описанную с помощью XML-конфигурации IoC-контейнера (подход был описан в статье журнала «Кибернетика и системный анализ»). Мы пошли дальше, начали описывать UI в виде XML-моделейи генерировали ASCX мегабайтами. Наступили на все грабли, на которые могли наступить. В проектах начали появляться сгенерированные XML-конфигурацииразмером 40mb и больше; был момент, когда большая часть системы задавалась в виде сложных XML структур, после чего пришло понимание, что не все XML-моделиодинаково полезны.

В 2008 часть наработок были открыты в виде open-source проекта Open NIC.NET (инфраструктурные компоненты), а все, что касалось MDD, было написано с чистого листа и названо NReco.

Разделение условное и просто сложилось исторически: на самом деле оба проекта развивались синхронно, как единое целое. Эта первая версия использовалась (и развивалась) для разработки десятков веб-проектов (2009-2013).Несмотря на открытость и очевидный (для нас) экономический эффект, технология была все еще достаточно сложной и запутанной (по разным причинам) для того, чтобы ее использовал кто-то кроме нашей команды.

В результате тотального рефакторинга и переосмысления накопленных наработок появилась полностью новая версия NReco 2.0, которая, я надеюсь, достойна внимания широкой аудитории.

Генерация NReco-приложения

При проектировании NReco 2.0 я старался максимально использовать существующую инфраструктуру VisualStudio. Например, при редактировании XML-моделейработает встроенная в VS-валидация и подсказки по XML-схемам,а все компоненты оформлены в виде NuGet-пакетов с активным использованием

XDT. Инфраструктурные компоненты, такие как IoC-контейнер или DALC, являются полностью автономными и могут быть использованы в любом .NET проекте.

Начать знакомство с NReco можно одним из 2-хспособов:
— Клонировать Git-репозиторий code.google.com/p/nreco (бранч nreco2) и запустить несколько примеров
— Сгенерировать готовое ASP.NET приложениев виде NuGet-пакета.

Дополнительную информацию можно обнаружить на сайте nrecosite.com. Рассчитывать на полноценную документацию пока не приходится: может быть, у меня появится свободное время (ага, а курс снова будет 8грн), или, может, появятся новые контрибьюторы, или что-то еще. С другой стороны, благодаря наличию XML-схеми описанию трансформаций в виде XSL вполне посильно разобраться, что к чему.

Рассмотрим процесс генерации ASP.NET как наиболее эффектный. Допустим, нам нужен прототип для гипотетической мини-CRM с контактами клиентов и сопутствующими справочниками. Чтобы не усложнять процесс настройкой базы, изменим БД на SQLite:

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

Далее расположен конструктор для определения схемы данных и CRUD-интерфейса. Определим таблицы для справочников:

Для таблиц-справочников CRUD Type выберем Editable List, чтобы удобно было набить значения прямо в списке.

Также добавим таблицу с клиентами, которая будет использовать определенные выше справочники:

Генерация приложения — это тоже трансформация XML-модели (формируется по введенным данным) в набор файлов (в основном других XML-моделей),которые сформируют уникальный NuGet-пакет для установки в проект VisualStudio.

Установка сгенерированного пакета не должна вызвать особых трудностей: после генерации отображается подробная пошаговая инструкция. В целях тестирования проще всего создать в VisualStudio 2013 (Express for Web подойдет) новый ASP.NET Application Project с шаблоном Empty и core references для WebForms, и сразу установить только что скачанный NuGet-пакет (момент: VS Update 2 должен быть установлен, иначе при установке пакета вывалится ошибка).

Если все прошло успешно, можно запустить приложение нажатием F5, при первом запуске приложение само создаст файл с SQLite базой и инициализирует ее схему. В результате должна отобразиться логин-страница:

В базе по умолчанию создана учетная запись «admin» с паролем «1». После входа наполняем справочники:

И создаем запись для клиента:

Список клиентов, страница с деталями и редактированием прилагаются.

Собственно, это и есть обещанный (абсолютно работоспособный) прототип, который можно получить за несколько минут.

Все артефакты представлены в виде XML-моделейи легко поддаются расширению/модификации путем редактирования в VisualStudio; рассмотрим процесс добавления нового поля:

После изменения XML-моделинадо повторить процесс трансформации модели, который происходит при каждой сборке проекта. Технически это реализовано особым MSBuild Task-ом, который вызывается на AfterBuild проекта для всех файлов проекта, где указан Build Action = XmlModel или которые имеют расширение *.dsm.config.

Этот Task ожидает, что у каждого файла с XML-моделямибудет processing instruction с информацией о том, как трансформировать эту модель. Например, для 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).

Бинго! Этого достаточно, чтобы указать, какие XML-моделитрансформировать, каким образом и где расположить результат. Все просто до неприличия, а значит, с этим сможет разобраться даже начинающий девелопер.

Конечно, считать XSL полноценным языком трансформаций можно только для преобразований XML → XML, однако в случае ASP.NET-приложения этого вполне достаточно: конфигурация IoC-контейнера описывается с помощью XML, а UI-шаблоны (ASPX/ASCX) описываются XML-подобнымспособом. Вообще говоря через XSL можно генерировать любые текстовые артефакты (в том числе и JavaScript/C# код), но в этом случае XSL не сможет обеспечить некоторые характеристики трансформации (например, синтаксическую корректность результата) .

Основная магия происходит в XSL-правилах и компонентах, композиция которых приводит к появлению требуемой функциональности.

Под капотом NReco осталось еще много интересного: механизмы связывания с использованием функциональных зависимостей, автоматическое согласование типов (и делегатов!), событийно-ориентированная организация логики приложения и всякое такое. В этой вводной статье нет возможности раскрыть все технические детали фреймворка, который создавался много лет. Но я надеюсь, что изложенного материала достаточно, чтобы вызвать интерес к проекту NReco; особо стойкие могут продолжить знакомство с инструментом через изучение исходных кодов и примеров/тестов, а также просто экспериментируя.

Возможности

Список того, что можно сделать с XML-моделями«из коробки», не ограничивается простейшими CRUD-ами:
— можно задавать произвольные конфигурации рендеринга (в несколько колонок, в табах и т.д.);
— к спискам можно определять фильтры, в том числе достаточно сложные (условия на несколько полей с AND/OR);
— использовать массовые операции в списках;
— использовать произвольные UserControl-ы для рендеринга кастомных элементов или редакторов полей;
— декларативно описывать зависимости между редакторами на формах (классика жанра, 2 зависимых дропдауна, в таком духе);
— определять новые элементы в XML-моделях (например, для описания специфического оформления в конкретном проекте);
— отображать в виде диалогов, абстрактные формы (не привязанные к какой-то таблице; например, для бизнес-действий);
— задавать произвольные SQL-view для использования в провайдерах данных и UI;
— централизовано ограничивать доступ к данным на уровне SQL запросов;
— включить встроенную реализацию отслеживания изменений данных в БД (change data capture / change data tracking).

Этот минимальный набор фичей уже позволяет использовать NReco для быстрого построения админок и разнообразных бизнес-приложений (как минимум, их прототипов). В дальнейшем список доступных XML-моделейбудет расширен: некоторые классные фичи из предыдущей версии NReco (например, XML-модельдля описания индексации и поиска с помощью Lucene.NEТ) все еще ждут рефакторинга и оформления в виде NuGet-пакетов.

Помимо готовых моделей для описания слоя данных и UI, можно воспользоваться инфраструктурой NReco для определения своих XML-моделейи их трансформаций в результирующие файлы ASP.NET приложения. Таким образом можно организовать повторное использование артефактов как внутри проекта, так и между проектами, выделяя целые блоки функциональности в виде NuGet-пакетов.

Вместо заключения

Мне кажется, разработка в аутсорсинге наиболее брутальная. Временные и бюджетные ограничения всегда на первом месте, и любой новый подход проходит жесткую аппробацию реальностью и экономической целесообразностью. Каждый по-своему, но мы все таки используем объектно-ориентированный и компонент-ориентированный подходы в ежедневной разработке. С модель-ориентированной разработкой (MDD) как-то не сложилось — видимо, всё дело в реализации.

Технология NReco сформировалась и выжила в суровых условиях украинского аутсорсинга (более того, в небольшойкоманде, где каждый человек на счету); она не претендует на фундаментальность (как например, MDA от OMG), но при этом позволяет получить выгоды от использования подхода MDD в совершенно обычных веб-проектах уже сейчас, с минимальными затратами на внедрение и обучение.


Viewing all articles
Browse latest Browse all 8115

Trending Articles