MVC: Репозитории и Услуги - PullRequest
       10

MVC: Репозитории и Услуги

5 голосов
/ 15 января 2009

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

Другими словами: должны ли службы делать различные запросы Linq to SQL в репозитории? Или все запросы должны быть предопределенными в репозитории, и бизнес-логика просто решает, какой метод вызывать?

Ответы [ 3 ]

11 голосов
/ 15 января 2009

Вы действительно подняли здесь вопрос, который в настоящее время вызывает много дискуссий в сообществе разработчиков - см. Последующие комментарии к Должен ли мой репозиторий предоставлять IQueryable?

Хранилище может - и должно - создавать сложные комбинированные объекты, содержащие несколько связанных объектов. В доменном дизайне они называются агрегатами - коллекциями связанных объектов, организованными в некую связную структуру. Ваш код не должен вызывать GetCustomer(), GetOrdersForCustomer(), GetInvoicesForCustomer() отдельно - вы просто вызываете myCustomerRepository.Load(customerId), и вы получаете глубокий объект customer с уже созданными экземплярами этих свойств. Я также должен добавить, что если вы возвращаете отдельные объекты на основе определенных таблиц базы данных, то это совершенно правильный подход, но на самом деле это не репозиторий per se - это просто слой доступа к данным.

С одной стороны, существует убедительный аргумент в пользу того, что объекты Linq-to-SQL с их «умными» свойствами и их отложенным выполнением (т.е. без загрузки Customer.Orders, пока вы на самом деле не используете его), являются полностью допустимой реализацией шаблон репозитория, поскольку на самом деле вы не выполняете код базы данных, вы выполняете операторы LINQ (которые затем преобразуются в код БД базовым поставщиком LINQ)

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

2 голосов
/ 15 января 2009

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

2 голосов
/ 15 января 2009

Репозиторий должен быть единственным компонентом вашего приложения, который знает что-нибудь о вашей технологии доступа к данным. Поэтому он вообще не должен возвращать объекты, сгенерированные L2S, а сопоставлять эти свойства с собственными объектами модели.

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

...