Подтвердить что ты не робот

Какая конкретная проблема решает проблему репозитория?

(Примечание. Мой вопрос очень похож на человека, который задал этот вопрос три месяца назад, но на него никогда не отвечали.)

Недавно я начал работать с MVC3 + Entity Framework, и я продолжаю считать, что наилучшей практикой является использование шаблона репозитория для централизации доступа к DAL. Это также сопровождается пояснениями, что вы хотите сохранить DAL отдельно от домена и особенно слоя представления. Но в примерах, которые я видел, репозиторий (или кажется) просто возвращает DAL-сущности, то есть в моем случае репозиторий будет возвращать объекты EF.

Итак, мой вопрос: насколько хорош репозиторий, если он возвращает только объекты DAL? Разве это не добавляет слой сложности, который не устраняет проблему прохождения объектов DAL между слоями? Если шаблон репозитория создает "единственную точку входа в DAL", как это отличается от контекстного объекта? Если репозиторий предоставляет механизм для извлечения и сохранения объектов DAL, как это отличается от контекстного объекта?

Кроме того, я прочитал хотя бы одно место, в котором шаблон "Единица работы" централизует доступ к репозиторию для управления объектами (объектами) данных, но я не понимаю, почему это тоже важно.

Я 98.8% уверен, что здесь что-то не хватает, но из моих чтений я этого не видел. Конечно, я просто не могу читать правильные источники...:\

4b9b3361

Ответ 1

Entity Framework DbContext в основном напоминает репозиторий (и блок работы). Вы не обязательно должны абстрагировать его в простых сценариях.

Основным преимуществом репозитория является то, что ваш домен может быть неосведомленным и независимым от механизма сохранения. В архитектуре, основанной на уровне, зависимости зависят от уровня пользовательского интерфейса от домена (или обычно называемого уровня бизнес-логики) до уровня доступа к данным. Это означает, что пользовательский интерфейс зависит от BLL, который сам зависит от DAL.

В более современной архитектуре (распространяемой с помощью доменного проектирования и других объектно-ориентированных подходов) домен не должен иметь внешних зависимостей. Это означает, что пользовательский интерфейс, механизм сохранения и все остальное должны зависеть от домена, а не наоборот.

Затем репозиторий будет представлен через свой интерфейс внутри домена, но имеет свою конкретную реализацию за пределами домена, в модуле сохранения. Таким образом, домен зависит только от абстрактного интерфейса, а не от конкретной реализации.

Это в основном объектно-ориентированное или процедурное программирование на архитектурном уровне.

См. также Порты и адаптеры a.k.a. Шестиугольная архитектура.

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

Ответ 2

Я думаю, что термин "репозиторий" обычно считается так, как "шаблон репозитория" описывается в книге Шаблоны архитектуры корпоративных приложений от Мартина Фаулера.

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

Поверхность Entity Framework выполняет все это и может использоваться как простая форма репозитория. Однако в репозитории может быть больше, чем просто абстракция уровня данных.

Согласно книге Domain Driven Design Эрика Эванса, у репозитория есть следующие преимущества:

  • Они представляют клиентам простую модель для получения объектов персистентности и управления их жизненным циклом.
  • Они отделяют разработку приложений и доменов от технологии персистентности, нескольких стратегий баз данных или даже нескольких источников данных.
  • Они сообщают проектные решения о доступе к объекту
  • Они позволяют легко подменять фиктивную реализацию, для модульного тестирования (обычно с использованием коллекции в памяти).

Первая точка примерно соответствует приведенному выше параграфу, и легко видеть, что сама платформа Entity Framework легко ее выполняет.

Некоторые утверждают, что EF выполняет вторую точку. Но обычно EF используется просто, чтобы превратить каждую таблицу базы данных в объект EF и передать ее в пользовательский интерфейс. Это может быть абстрагирование механизма доступа к данным, но он вряд ли абстрагирует структуру реляционных данных за кулисами.

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

Что касается третьего преимущества, EF ничего не сделает (с точки зрения DDD), чтобы помочь. Обычно DDD использует репозиторий не только для абстрактного механизма сохранения данных, но также для ограничения ограничений доступа к определенным данным:

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

Другими словами, у вас не будет "AddressRepository", потому что у вас есть таблица адресов в вашей базе данных. Если ваш проект решает управлять доступом к объектам Address таким образом, PersonRepository - это то, где вы определяете и применяете выбор дизайна.

Кроме того, репозиторий DDD обычно будет содержать инкапсулированные определенные бизнес-концепции, относящиеся к наборам данных домена. У OrderRepository может быть метод OutstandingOrdersForAccount, который возвращает определенное подмножество ордеров. Или репозиторий клиента может содержать метод PreferredCustomerByPostalCode.

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

Что касается четвертого преимущества, хотя я уверен, что есть определенные стратегии, которые могут позволить заменять файл datacontext, обертывая его в репозиторий, он делает его простым.

Что касается "Единицы работы", вот что должна сказать книга DDD:

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

Ответ 3

Вы правы, в этих простых случаях репозиторий - это просто другое имя для DAO, и оно приносит только одно значение: тот факт, что вы можете переключить EF на другую технологию доступа к данным. Сегодня вы используете MSSQL, завтра вам понадобится облачное хранилище. ИЛИ используя микро orm вместо EF или переключение с MSSQL на MySql.

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

Там также ограниченный случай, когда вы получаете информацию из нескольких источников (db + файловая система), репо будет действовать как фасад, но это еще одно имя для DAO.

Реальный реальный репозиторий действителен только тогда, когда вы имеете дело с областями/бизнес-объектами, для приложений с центрами данных, которые не изменят память, достаточно одного ORM.

Ответ 4

Это было бы полезно в ситуациях, когда у вас есть несколько источников данных и вы хотите получить к ним доступ с использованием последовательной стратегии кодирования.

Например, у вас может быть несколько моделей данных EF, а некоторые данные доступны с использованием традиционных ADO.NET с сохраненными процессами, а некоторые данные доступны с использованием стороннего API, а некоторые из них доступны из базы данных Access, живущей на сервере Windows NT4 сидя под одеялом пыли в шкафу вашей метлы.

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

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

Ответ 5

Учитывая ваш сценарий, я просто хотел бы выбрать набор интерфейсов, которые представляют, какие структуры данных (ваши модели доменов) должны быть возвращены с вашего уровня данных. Ваша реализация может быть смешением EF, Raw ADO.Net или любого другого типа Хранилища данных/Провайдера. Ключевая стратегия здесь заключается в том, что реализация абстрагируется от непосредственного потребителя - вашего уровня домена. Это полезно, если вы хотите unit test объекты своего домена, а в менее распространенных ситуациях - вообще изменить платформу поставщика данных/базы данных.

Вы должны, если у вас уже есть, рассмотреть возможность использования контейнера IOC, поскольку они упрощают связь вашего решения с помощью Инъекция зависимостей. Есть много доступных, лично я предпочитаю Ninject.

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

Ответ 6

Еще одна вещь, которую следует учитывать, - это то, что даже когда вы знаете, что будете работать с одним хранилищем данных, все же может возникнуть смысл создать абстракцию репозитория. Причина в том, что может быть функция, которую требуется вашему приложению, чтобы ваш ORM du jour либо плохо работал (производительность), либо вовсе, либо просто не знал, как сделать ORM изгибом в соответствии с вашими потребностями.

Если вы обертываете ORM за хорошо продуманный интерфейс репозитория, вы можете легко переключаться между различными технологиями по своему усмотрению. В моих репозиториях не редкость видеть, что некоторые методы используют EF для их работы, а другие - использовать что-то вроде PetaPoco или (gasp) код ADO.net. Абстракция репозитория позволяет вам использовать именно тот инструмент, который подходит для этой задачи, без утечки этих сложностей в код клиента.

Ответ 7

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

По-моему, репозиторий в этом чистом виде IEnumerable, в то время как вы и многие статьи говорят о "службе доступа к данным".

Я писал об этом здесь.