Pull to refresh

Comments 11

Так и не понял, какая проблема решалась. И какая решилась, впрочем, тоже.
Возможно, я слишком увлёкся технической составляющей.
  1. Уход от явного использования DBContext, который используется только в регистрации.
  2. CRUD над источником данных, сразу зарегистрированный в контейнере для любой сущности, реализующей определенный интерфейс.
  3. Возможность строить нетривиальные запросы к репозиторию, которые транслируются в IQueryable.
  4. И всё это без написания кода самих репозиториев: generic даёт достаточно функциональности.

Очень удобно для новых и особенно некрупных (до 100.000 строк) проектов, когда модель данных меняется в процессе уточнений — можно написать POCO-объект и к нему сразу появится готовый репозиторий в контейнере. Пишите только бизнес-логику, не инфраструктуру.
1. С какой целью
2. Сводится в п.1
3. Сводится к п.1
4. Снова сводится к п.1

Итого, какая проблама решается «уходом от явного использования DBContext»?
Почему не стоит использовать явно в бизнес-логике конкретную технологию доступа к данным?
Во-первых, можно создать другую реализацию IRepository и работать с другим источником. Достаточно будет реализовать репозитории, не потребуется переписывать весь код, который использовал DBContext. Скрее всего достаточно будет поправить 2 класса — RepositoryBase и RepositoryContext.
Во-вторых (сводится к п.1), можно легко замокать репозиторий и написать юнит-тест на бизнес-логику.
В-третьих, простота расширения. Из реализации на GitHub я удалил часть интерфейса IRepository, связанного с использованием автомаппинга и извлечения недоменных объектов, связанных через AutoMapper с Entity, но достаточно добавить этот код в одном месте и он станет доступен для всех сущностей.

Я согласен, что репозиторий сам по себе является спорным шаблоном, есть UoF и CQRS, но статья немного о другом.
> Почему не стоит использовать явно в бизнес-логике конкретную технологию доступа к данным?
Ну так для того, чтобы не использовать конкретную технологию, достаточно абстрагировать DbContext за интерфейсом — и все.

(все, конечно, не так прямолинейно, но в общих чертах работает)
не получится — интерфейс никак не описывает Lazy Loading и Change Tracking. Поэтому другая реализация интерфейса легко ломает приложение.
Мне чаще всего нужно работать с detached entities, поэтому и то, и другое меня обычно волнует мало.
Поведение Вашей реализации репозитория целиком и полностью определяется именно поведением «конкретной технологии доступа к данным» в частности, при добавления в репозиторий entity со связанными entity сохранится весь граф. Это не является типичным поведением репозитория, очевидным из его интерфейса. Наивная реализация интерфейса репозитория на другой «технологии доступа к данным» легко поломает работающее приложение.

«Почему не стоит использовать явно в бизнес-логике конкретную технологию доступа к данным?» в чем тут проблема то? Хотите скрыть persistence от БЛ — скрывайте, но при чем тут репозитарий. Хотите чтобы любая ORM репозитарии представляла — тпк они это давно переросли, на UoW сидят уже. Хотите ужать все ORM до репозитариев и переключать их — на здоровье, если Вам репозитариев хватает. Фронт борьбы давно ушел дальше.

Про мокание
EF нельзя полностью замокать именно потому, что он предоставляет такую функциональность, как Change Tracking, Lazy Loading, In-Memory collections которые поощряют неявное их использование и написание полноценного теста с моками потребовало бы отслеживания кучи вызовов. Поэтому я первым делом указал, что Ваша реализация репозитория «течет» сторонними эффектами и мокание его в простых тестах не означает работоспособность в более сложном сценарии. А течет она из-за того самого change tracking в EF, который как раз и не мешает этот самый EF мокать.

Про расширение.
Да, действительно, если сначала образать EF, то потом получившееся можно расширить. Чем сильнее обрезать, тем проще расширить. Обычно так. Исключения встречаются тоже.

Репозиторий вообщето совсем не спорбый шаблон. А вот занятие по превращению UoW в набор репозиториев — спорное.
Нашёл довольно интересные идеи о репозиториях в соседней статье. Во-первых, созданием репозиториев управляет UoW, что подразумевает использование одного контекста всегда, Во-вторых, репозиторий представляется как интерфейс доступа к IQueryable Table. Вполне вероятно, что следующая версия библиотеки эти идеи реализует.
Комментарии к «соседней статье», где показывается несостоятельность этой идеи, вас, видимо, не смутили?
Sign up to leave a comment.

Articles