Универсальный репозиторий с EF 4.1 в чем смысл

По мере того, как я углубляюсь в DbContext, DbSet и связанные с ними интерфейсы, я удивляюсь, почему вам нужно реализовать отдельный "универсальный" репозиторий вокруг этих реализаций?

Похоже, что DbContext и IDbSet делают все, что вам нужно, и включают "Единицу работы" внутри DbContext.

Я что-то здесь упускаю или кажется, что людям нравится добавлять еще один уровень зависимости без причины.

3 ответа

Решение

Вы на самом деле правы. DbContext является реализацией единицы работы шаблона и IDbSet является реализацией шаблона хранилища.

Хранилища в настоящее время очень популярны и чрезмерно используются. Все используют их только потому, что существуют десятки статей о создании репозитория для структуры сущностей, но на самом деле никто не описывает проблемы, связанные с этим решением.

Основными причинами использования репозитория обычно являются:

  • Скрыть EF из верхнего слоя
  • Сделайте код лучше тестируемым

Первая причина - это некая архитектурная чистота и отличная идея, что если вы сделаете свои верхние уровни независимыми от EF, вы сможете позже переключиться на другую среду персистентности. Сколько раз вы видели такую ​​вещь в реальном мире? По этой причине работа с EF значительно усложняется, поскольку в вашем хранилище должно быть много дополнительных функций, охватывающих то, что EF позволяет по умолчанию.

В то же время упаковка EF-кода может улучшить организацию вашего кода и следовать правилу разделения интересов. Для меня это может быть единственным реальным преимуществом хранилища и единицы работы, но вы должны понимать, что следование этому правилу с EF, возможно, сделает ваш код лучше поддерживаемым и лучше читаемым, но на начальном этапе создания вашего приложения оно будет намного выше и для небольших приложений это может быть ненужной сложностью.

Вторая причина частично верна. Большим недостатком EF является жесткая архитектура, которую трудно подделать, поэтому, если вы хотите выполнить модульное тестирование верхнего уровня, вы должны каким-то образом обернуть EF, чтобы допустить насмешку над его реализацией. Но это имеет много других последствий, которые я описал здесь.

Я слежу за блогом Айенде. Если вы когда-либо использовали NHibernate, вы, вероятно, знаете его статьи. Этот парень недавно написал несколько статей против использования репозитория с NHibernate, но NHibernate намного лучше насмешливый.

Я борюсь с теми же проблемами, и важна насмешливость для модульного тестирования уровней EF. Но я наткнулся на эту замечательную статью, в которой объясняется, как настроить EF 4.1 DbContext, чтобы он был надёжным, убедившись, что ваш производный DbContext реализовал общий интерфейс и предоставляет IDbSet, а не DbSet. Так как я использую подход Database First, поскольку наша база данных уже существует, я просто изменил шаблоны T4, использованные для генерации моего производного DbContext, чтобы он генерировал его для возврата интерфейсов IDbSet, а также из моего общего интерфейса. Таким образом, все это может быть легко смоделировано, и вам не нужно реализовывать собственную единицу работы или шаблон репозитория. Просто напишите свой сервисный код для использования вашего универсального интерфейса, а когда вы приступите к его модульному тестированию, просто смоделируйте универсальный интерфейс с конкретными тестовыми данными, и все готово.

http://refactorthis.wordpress.com/2011/05/31/mock-faking-dbcontext-in-entity-framework-4-1-with-a-generic-repository/

Одна из причин создания репозитория заключается в том, что вы можете скрыть реализацию DBSet и DbContext, если решите перейти от EntityFramework к чему-то другому или наоборот.

Например, я использовал NHibernate, и я обернул все вызовы к этой структуре в моих классах репозитория. Они возвращают IEnumerable для того, чтобы они были "универсальными", а мои репозитории имеют стандартные операции CRUD (обновление, удаление и т. Д.). Я давно перешел на Entity Framework. После этого мне не нужно было ничего менять в моих классах ViewModel или за их пределами, потому что они указывали на мой репозиторий - мне нужно было только изменить внутреннюю часть своего репозитория. Это значительно облегчило жизнь при миграции.

(Я использовал NHibernate, потому что мы подключаемся к ISeries, и в то время не было экономически эффективных реализаций, использующих EF с ISeries. Единственной доступной была оплата IBM $12 000 за их DB2Connect)

Другие вопросы по тегам