Здравствуйте, Vladek, Вы писали:
V>Здравствуйте, gandjustas, Вы писали:
G>>Это не является ответом на вопрос зачем он нужен. Ты можешь миллион классов придумать, со своими функциями, но это не оправдывает их существования.
G>>Тем более реальной выборкой данных нанимается ORM, а репозиторий только обертка, которая ничего положительного не приносит в код.
V>Скрыть механизм хранения данных от других слоёв приложения.
Какая от этого польза? Вред мы уже видели, а польза где?
V> Репозиторий оперирует коллекциями объектов, описывающих предметную область программы.
Этими же коллекциями оперирует все остальное приложение. Иначе model binding не будет работать.
V>Его контракт свободен от деталей того, какая технология используется внутри него. Это позволяет писать простой код как внутри репозитория, так и снаружи его. Простой код означает, что я быстрее закончу свою работу сейчас и быстрее внесу изменения потом. Простой код — это свободное время, которое я трачу в собственное удовольствие и не думаю о неработающем коде или хитроумном баге.
У тебя получается более сложный код. Потому что потребитель твоего репозитария вынужден формировать класс DataFetch, а внутри репозитария надо этот DataFetch разбирать и собирать Linq запросы. Так еще и статической проверки DataFetch нету.
Не веришь? так попробуй реализовать сценарии, которые я приводил:
1) Показывать посты по дате добавления
2) Показывать посты по количеству оценок за день (самые популярные)
3) Показывать посты по комментов за день (самые обсуждаемые)
Сравни с объемом кода, скоростью разработки и затратами на поддержку без репозитариев
G>>И как это онсоится к репозитарию?
G>>"Здесь и сейчас" можно добиться, написав Linq прямо в контроллере. А "легко поддаваться изменениям и оставаться полезным" можно добиться сделав комбинаторы, примерно вот так: http://gandjustas.blogspot.ru/2010/05/iqueryable-generics.html?&tpwf_mode=main
G>>А какая польза от репозитория?
V>V>IEnumerable<EntityDetails> visibleEntities = repo.GetEntities(new EntityFetch { Visible = true });
V>
Я могу легко создать десятки интерфейсов-аспектов и комбинаторов к ним, а ты все поместишь в EntityFetch ? Прости, но такое решение будет неюзабельным совершенно. Да и какая гарантия в твоем коде что сущность вообще поддерживает нужный аспект? Никакой. Поэтому получаем больше ошибок и больше кода.
V>И простая читабельная реализация метода GetEntites. Без велосипеда IVisible и костыля к нему FixupVisitor. Хотя бы название метода Fix — не заставило задаться вопросом о целесообразности решения?
Ты комменты прочитай, нет необходимости в этом методе, достаточно написать T:class
V>>>Положительные эффекты в разделении зон ответственности кода. Если тебе надо работать с кодом доступа к бд, ты делаешь это в одном месте и не тебе не приходится лазать по всему дереву исходников. В будущем, тебе не придётся долго искать этот код и потом читать половину проекта, чтобы внести изменения и быть уверенным, что ничего не забыто.
G>>Весь код работы с БД находится в ORM, а запросы "в одном месте" это фантастика, потому что в каждом контроллере нужны разные запросы. Где-то нужны сортировки, где-то проекции итп. Очень редко запросы дублируются.
V>Их конечное количество и мы не тратим время на написание универсальных велосипедов.
Ты выше показываешь как раз "универсальный велосипед" со своим EntityFetch.
V>>>Этот IEnumerable будет содержать с десяток объектов, уже готовых для отображения пользователю. Любые манипуляции с ним не будут отличаться большими накладными расходами.
G>>А где гарантия что десятки?
G>>Откуда репозиторий узнает что нужно для отображения пользователю?
V>V>DataFetch.PageSize
V>
А проекция? как ты её задавать будешь? А нетривиальные фильтры?
V>А про пользователя репозиторий ничего не знает.
Вот в этом и проблема. Значит запросы будут гораздо менее эффективными от применения репозитариев. А польза в чем?
G>>С такими рассуждениями у тебя вся логика уедет в репозитории и методы репозиториев будут 1-в-1 повторять контроллеры. А проблемы никуда не денутся.
V>Логика выборки данных для набора конкретных случаев, которые нужны в приложении. И, главное, код будет простой как доска.
Так покажи пример. Ты пока что показываешь только усложнения.
Я вообще не понимаю где будет упрощение, если у тебя внутри репозитариев такой же Linq, но параметры ты передаешь через дополнительный (!) класс EntityFetch, с которым ошибиться на порядок проще. Кода больше, ошибок больше, где "простой как доска"?