
Generic Repository обещал три вещи — не сдержал ни одной и забрал доменную модель
vsinyavsky 40 минут назад Generic Repository обещал три вещи — не сдержал ни одной и забрал доменную модель Средний 9 мин 798 .NET * C# * Проектирование и рефакторинг * Программирование * Мнение Generic-репозиторий в...
Anthropic — What company has the best second artificial intelligence model at the end of June?
В сфере искусственного интеллекта произошло заметное событие. vsinyavsky 40 минут назад Generic Repository обещал три вещи — не сдержал ни одной и забрал доменную модель Средний 9 мин 798 . NET * C# * Проектирование и рефакторинг * Программирование * Мнение Generic-репозиторий в том проекте прожил полгода, прежде чем я понял, что он стоит нам дороже, чем экономит. Поиск отелей, Mongo, две тысячи строк вокруг одного God-сервиса – и поверх всего этого аккуратный IRepository, который обещал, что про Mongo знает только инфраструктура.
Сломалось на простой просьбе продакта. Рядом с результатами поиска – счётчики по городам и гистограмма цен, одним запросом. В Mongo это один aggregation pipeline через $facet: база сама группирует и считает, наружу отдаёт готовые числа.
Технические детали
Написать это через наш репозиторий оказалось нельзя – не сломав ровно ту абстракцию, ради которой его и заводили. Репозиторий отдавал наружу IReadOnlyList через Find(predicate) – честный контракт, не светящий ни IQueryable, ни Mongo. Чтобы построить фасеты, разработчик вызывал Find с фильтром, получал всю выборку в память и группировал её LINQ’ом.
На стейджинге с двумя сотнями отелей это летало. На проде с полным инвентарём – клало эндпоинт: вся выборка ехала из Mongo в приложение, чтобы посчитать то, что Mongo посчитал бы сам за один проход. Очевидная починка – добавить в репозиторий метод SearchWithFacets(...
Но этот метод чистый Mongo, его не реализуешь над SQL без слёз. В ту секунду, когда он появляется в IRepository, репозиторий перестаёт быть тем, чем себя объявлял – хранилищенезависимой абстракцией. Либо он течёт, либо тащит всё в память.
Отраслевые последствия
Третьего наш дизайн не предлагал. Это был не баг реализации, а природа самого паттерна – и за полгода он успел набрать ещё два таких же провала. Generic Repository продаётся под три обещания:подменяемость хранилища – домен не знает, Mongo под ним или Postgres;тестируемость – подменим базу моком и проверим логику без неё;меньше кода – один набор CRUD-методов на все типы сразу.
На том проекте он не сдержал ни одного – и попутно забрал доменную модель. Корень один: персистентность тут – не одна задача, а две: запись агрегатов с инвариантами и произвольные проекции на чтение. Натянешь на них одну универсальную абстракцию – и она рвётся по очереди на каждом обещании.
Разберу по обещанию, а в конце покажу, чем мы его заменили. Обещание первое: подменяемость хранилищаСила, ради которой репозиторий обычно и продают: домен не знает, что под ним – Mongo, Postgres или in-memory в тестах. Захотим сменить хранилище – перепишем инфраструктуру, домен не заметит.
Событие, по словам экспертов, усилит конкуренцию в сфере ИИ.





