Общий репозиторий с EF 4.1, в чем смысл

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

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

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

Ответ 1

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

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

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

  • Скрыть EF от верхнего уровня
  • Сделать код более надежным.

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

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

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

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

Ответ 2

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

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

Ответ 3

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

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

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