Чем больше сообщество вложится в мост, тем мощнее инструмент«DomainCraft» — рабочее название
DomainCraft

23 августа 2026 г. · 3 мин чтения

От монолита к осям и слоям: почему один мост превратился в стек

Как из 71-шаблонного монолита родилась идея осей и слоёв, почему C#-мост разобрали на четыре независимых репозитория и что это значит для будущего DomainCraft.

История одной модернизации: монолит на 71 шаблон, идея «один слой — один репозиторий», бит-идентичный вывод и математика, которая превращает N×M в N+M.

Всё началось с неудобного вопроса: «Что будет, если мостов станет тысяча?»

DomainCraft — это компилятор доменной модели. Один domain.yaml, много мостов — каждый мост рендерит код для своего языка и своего слоя продукта. Но на старте у проекта был только один мост — и это был монолит.

Как всё начиналось: монолит csharp-restful

Первый мост появился, когда мы только начинали: C# + ASP.NET Core + EF Core + PostgreSQL + JWT. Он был один, но внутри — 71 шаблон, которые вместе выводили весь проект: от Domain до WebApi, от сущностей до контроллеров, от Dockerfile до тестов. Он всё делал — но как одна неделимая масса.

Проблемы начались, как только мы захотели больше целевых стеков. Каждый следующий мост в этой модели требовал полной дорожки шаблонов — даже если отличался от существующего лишь на пару слоёв. А каждое дополнение в одном измерении (новый способ хранения данных, новый транспорт) умножалось на все остальные.

Посчитайте сами: 10 способов хранения × 10 способов отдавать API = 100 мостов, каждый по 71 шаблону. 7 100 шаблонов, которые нужно поддерживать параллельно. Это не масштабировалось в принципе.

Идея осей и слоёв

Мы поняли: язык — это вертикаль, но внутри неё есть горизонтальные уровни, которые почти не меняются от комбинации к комбинации. Любой C#-стек начинается с одного и того же тонкого ядра: сущности, enum-ы, схема запросов, права. Дальше вверх идут ролевые слои: домен (сервисы, порты), персистенция (EF Core или Dapper), транспорт (REST, gRPC).

Так родились оси и слои — одна ось на независимое направление продукта, внутри оси — стек слоёв. Полное описание — в статье Оси и слои:

бэкенд C#:      core → domain → persistence → transport
фронтенд web:   ts-core → ts-client → react-rest
мобильный:      dart-core → flutter-rest → flutter-offline (в планах)

Слой — это маленькая единица в одном репозитории. Не 71 шаблон, а 4–10. Каждый репо отвечает только за свой слой и не знает про остальные.

Правило простое: один слой = один репозиторий — как это объявляется, показано в разделе «Механизм». И математика раскладывается: N вариантов персистенции × M вариантов транспорта — это N+M репозиториев, а не N×M. Десять способов хранить × десять способов отдавать = 22 репозитория (тонкое ядро + доменный слой + 10 + 10), а не 100. Тридцать × тридцать = 900 комбинаций, но 62 репозитория.

Механизм: extends и --replace

Мост ссылается на другой мост через extends, и ядро собирает цепочку: база рендерится первой, адаптер накладывается сверху, конфликты решаются в пользу адаптера. type_mappings, шаблоны и хелперы наследуются по всей цепочке.

Связь между слоями — две строки в bridge.yaml:

name: csharp-efcore
layer: persistence
extends: csharp-domain

Подмена одного слоя — это флаг в команде generate (см. справку по CLI):

domaincraft generate --bridge csharp-rest --replace persistence=csharp-dapper
# core + domain + dapper + rest

Без форков. Новая персистенция или новый транспорт — это отдельный маленький репозиторий, а не копия мира.

Модернизация в цифрах и фактах

Мы не запускали это вслепую: собрали новый стек из четырёх репозиториев и сравнили его вывод с монолитом на двух эталонных моделях — compliance-suite/kitchen-sink.yaml и examples/domain.yaml. Результат — побитово идентично: 187 файлов в kitchen-sink, 142 в example, ноль отличий. Монолит csharp-restful остался в истории как архив, а новые проекты рендерятся через четыре слоя.

То же на фронтенде: тонкое ядро ts-core (типы, query, permissions) сертифицируется один раз, ts-client добавляет валидацию и fetch-клиент (Zod + JWT), а react-rest — буквально три шаблона клея на TanStack Query. Подробнее о том, как устроен каждый слой — в списке мостов.

Что это меняет для будущего

  • Новые языки заходят быстрее. Тонкое ядро — недорогой фундамент: вся линейка стеков языка растёт из одного маленького ядра, а не из 71 шаблона.
  • Качество держится тестами. У каждого тонкого ядра — свой TCK: рукописный контракт, который не повторяет ошибки моста. Об этом — как устроена сертификация.
  • Сообществу открыт путь. Добавить свой слой (персистенцию, транспорт, фреймворк) — это 2–3 шаблона и прогон тестов, а не написание стека с нуля.

То, что начиналось с одного 71-шаблонного монолита, превратилось в архитектуру, которая готовит DomainCraft не к двум языкам, а к десяти — и к любой N×M комбинации внутри них.

Попробуйте сегодня — четыре слоя в одном выводе:

domaincraft generate --domain domain.yaml --bridge csharp-rest