Универсальный репозиторий с EF 4.1 в чем смысл - PullRequest
145 голосов
/ 11 апреля 2011

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

Похоже, DbContext и IDbSet делают всевам нужно включить "Unit Of Work" в DbContext.

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

Ответы [ 3 ]

202 голосов
/ 12 апреля 2011

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

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

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

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

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

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

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

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

21 голосов
/ 07 июня 2011

Я борюсь с теми же проблемами, и важна насмешливость для модульного тестирования слоев 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/

5 голосов
/ 24 февраля 2012

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

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

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

...