Использование шаблона репозитория для поддержки нескольких провайдеров

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

Например, предположим, что я хочу использовать Entity Framework для своего приложения. Однако, Я также хочу, чтобы набор тестовых данных был реализован в виде жестко запрограммированных списков. Я хотел бы иметь набор интерфейсов (IUserRepository, IProductRepository и т. Д. - давайте пока не будем говорить о более общем IRepository ), экземпляры которых могут быть созданы обоими подходами. Затем, используя (скажем) инструмент внедрения зависимостей, такой как Ninject или Castle Windsor, я могу переключаться между поставщиком инфраструктуры сущностей (доступ к реальной базе данных) и поставщиком тестов (доступ к спискам).

В двух словах. , вот проблема:

- Если вы собираетесь использовать Entity Framework, вы хотите, чтобы ваши репозитории возвращали IQueryable .

- Если вы собираетесь использовать жестко запрограммированные списки, вы НЕ хотите, чтобы ваши репозитории возвращали IQueryable, потому что это значительно увеличивает накладные расходы и, кроме того, Linq to Entities значительно отличается от Linq to Objects, вызывая множество головных болей в коде, который является общим для обоих провайдеров.

Другими словами, я обнаружил, что лучший подход изолирует весь EF-зависимый код в репозиториях, поэтому что сами репозитории возвращают IEnumerable или IList или что-то в этом роде - тогда и EF, и некоторые другие технологии могут использовать одни и те же репозитории. Таким образом, все IQueryable будут содержаться ВНУТРИ репозиториев EF. Таким образом, вы можете использовать Linq to Entities с репозиториями EF и Linq to Objects с репозиториями Test.

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

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

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

Есть идеи? Если бы кто-нибудь мог указать мне пример реализации, которая решает эту проблему, я был бы очень признателен. (Я много читал, но не могу найти ничего, что конкретно говорило бы об этих проблемах.)

ОБНОВЛЕНИЕ:

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

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

14
задан tereško 2 February 2014 в 10:46
поделиться