Это одно и то же? Только что закончил смотреть Учебник Роба Коннери на витрине, и они, похоже, похожи по технике. Я имею в виду, что когда я реализую объект DAL, у меня есть методы GetStuff, Add / Delete и т. д., И я всегда сначала пишу интерфейс, чтобы потом переключить db.
Я что-то путаю?





Насколько я понимаю, они могут означать в основном одно и то же, но название зависит от контекста.
Например, у вас может быть класс Dal / Dao, реализующий интерфейс IRepository.
Даль / Дао - это термин уровня данных; более высокие уровни вашего приложения думают о репозиториях.
Все дело в интерпретации и контексте. Они могут быть очень похожими или даже очень разными, но до тех пор, пока решение выполняет свою работу, то, что находится в названии!
Репозиторий - это шаблон, который можно применять разными способами, в то время как уровень доступа к данным несет очень четкую ответственность: DAL должен знать, как подключиться к вашему хранилищу данных для выполнения операций CRUD.
Репозиторий может может быть DAL, но он также может располагаться перед DAL и действовать как мост между уровнем бизнес-объекта и уровнем данных. Используемая реализация будет варьироваться от проекта к проекту.
Вы определенно не тот, кто все путает. :-)
Я думаю, что ответ на вопрос зависит от того, насколько пуристом вы хотите быть.
Если вам нужна строгая точка зрения DDD, это приведет вас по одному пути. Если вы посмотрите на репозиторий как на образец, который помог нам стандартизировать интерфейс уровня, разделяющего службы и базу данных, он приведет вас к другому.
С моей точки зрения, репозиторий - это просто четко определенный уровень доступа к данным или, другими словами, стандартизированный способ реализации вашего уровня доступа к данным. Есть некоторые различия между различными реализациями репозитория, но концепция одинакова.
Некоторые люди будут накладывать больше ограничений DDD на репозиторий, в то время как другие будут использовать репозиторий в качестве удобного посредника между базой данных и уровнем сервиса. Репозиторий, такой как DAL, изолирует уровень сервиса от специфики доступа к данным.
Одна проблема реализации, которая, кажется, отличает их друг от друга, заключается в том, что репозиторий часто создается с помощью методов, которые принимают спецификацию. Репозиторий вернет данные, удовлетворяющие этой спецификации. Большинство традиционных DAL, которые я видел, будут иметь больший набор методов, в которых метод будет принимать любое количество параметров. Хотя это может показаться небольшой разницей, это большая проблема, когда вы входите в области Linq и Expressions. Интерфейс нашего репозитория по умолчанию выглядит так:
public interface IRepository : IDisposable
{
T[] GetAll<T>();
T[] GetAll<T>(Expression<Func<T, bool>> filter);
T GetSingle<T>(Expression<Func<T, bool>> filter);
T GetSingle<T>(Expression<Func<T, bool>> filter, List<Expression<Func<T, object>>> subSelectors);
void Delete<T>(T entity);
void Add<T>(T entity);
int SaveChanges();
DbTransaction BeginTransaction();
}
Это DAL или репозиторий? В этом случае, я думаю, и то, и другое.
Ким
Возможно, IEnumerable <T> будет лучшим.
Я думаю, что IQueryable <T> был бы лучшим выбором, потому что он позволяет связывать методы и откладывать выполнение, позволяя базе данных делать всю работу.
Я бы хотел иметь возможность связывать методы вместе, но вся наша логика заключена в sprocs. Я собираюсь использовать этот шаблон, но без преимущества цепочки выражений.
Поскольку IQueryable<T> реализует IEnumerable<T> - разве последнего не хватит? Потребители, которым нужен IQueryable<T>, могли бы его использовать, а другим не пришлось бы?
@kenwarner Я думаю, что возвращение IQueryable <T> приводит к утечке абстракции. Вы должны вернуть объекты домена из своего репозитория.
Итак, в большинстве (простых) случаев DAO - это реализация репозитория?
Насколько я понимаю, кажется, что DAO имеет дело именно с доступом к db (CRUD - хотя и не выбирает ?!), в то время как Repository позволяет абстрагироваться от всего доступа к данным, возможно, являясь фасадом для нескольких DAO (возможно, разных источников данных).
Я на правильном пути?
На самом деле, я бы изменил это и сказал, что с упрощенной точки зрения репозиторий - это особый стиль реализации для DAO, но да, вы на правильном пути. (R из CRUD = Читать, так что это ваш выбор.)
Одно большое отличие состоит в том, что DAO - это общий способ работы с постоянством для любого объекта в вашем домене. С другой стороны, репозиторий имеет дело только с совокупными корнями.
Первое, что нужно понять, это то, что репозиторий как шаблон является частью более крупной системы, известной как Domain Driven Design. В домене DDD объекты сгруппированы в агрегаты, каждый из которых имеет агрегированный корень. Например. PurchaseOrder - это совокупный корень, а OrderItems - дочерние элементы в совокупном корне. Репозиторий имеет дело только с совокупными корнями. То есть, например, OrderItem никогда не загружается независимо от его совокупного корня. Таким образом, у вас никогда не будет репозитория OrderItem в DDD. Однако в системе без DDD у вас может быть OrderItemDao, поскольку Dao не ограничивается агрегированными корнями.
НГ, спасибо! Я начал видеть это таким образом, но теперь это проясняет. Мне нужно начать читать всю литературу по DDD!
@bingle, отличное описание совокупных корней и того, как дочерние объекты загружаются репозиторием. Где мог бы существовать репозиторий в многослойном приложении? Я мог видеть, что он находится в библиотеке уровня доступа к данным, но, поскольку он загружает дочерние объекты, должен ли он существовать в библиотеке уровня логики? Моя интуиция подсказывает мне уровень доступа к данным, но мне нужно ваше мнение по этому поводу.
Мое личное мнение таково, что все дело в отображении, см .: http://www.martinfowler.com/eaaCatalog/repository.html. Таким образом, вывод / ввод из репозитория - это объекты домена, которые в DAL могут быть любыми. Для меня это важное дополнение / ограничение, поскольку вы можете добавить реализацию репозитория для базы данных / службы / чего угодно с другим макетом, и у вас есть четкое место, где можно сосредоточиться на выполнении сопоставления. Если вы не должны использовать это ограничение и иметь сопоставление где-либо еще, то наличие разных способов представления данных может повлиять на код там, где он не должен изменяться.
Я искал ответ на аналогичный вопрос и согласен с двумя ответами с наивысшими оценками. Пытаясь прояснить это для себя, я обнаружил, что спецификации если, которые идут рука об руку с шаблоном репозитория, реализованы как первоклассные члены модели предметной области, тогда я могу
Я могу даже зайти так далеко и заявить, что шаблон репозитория пока не используется вместе с шаблоном спецификации, на самом деле это не «репозиторий», а DAL. Надуманный пример в псевдокоде:
specification100 = new AccountHasMoreOrdersThan(100)
specification200 = new AccountHasMoreOrdersThan(200)
assert that specification200.isSpecialCaseOf(specification100)
specificationAge = new AccountIsOlderThan('2000-01-01')
combinedSpec = new CompositeSpecification(
SpecificationOperator.And, specification200, specificationAge)
for each account in Repository<Account>.GetAllSatisfying(combinedSpec)
assert that account.Created < '2000-01-01'
assert that account.Orders.Count > 200
Подробнее см. Спецификационное эссе Фаулера (это то, на чем я основывал вышесказанное).
У DAL были бы специализированные методы, такие как
IoCManager.InstanceFor<IAccountDAO>()
.GetAccountsWithAtLeastOrdersAndCreatedBefore(200, '2000-01-01')
Вы можете видеть, как это может быстро стать громоздким, особенно с учетом того, что вам нужно определить каждый из интерфейсов DAL / DAO с этим подходом. и реализует метод запроса DAL.
В .NET запросы LINQ может являются одним из способов реализации спецификаций, но объединение спецификаций (выражений) может быть не таким гладким, как в случае собственного решения. Некоторые идеи для этого описаны в этот ТАК вопрос.
Во внешнем мире (то есть в клиентском коде) репозиторий такой же, как DAL, за исключением:
(1) его методы вставки / обновления / удаления ограничены использованием объекта контейнера данных в качестве параметра.
(2) для операции чтения может потребоваться простая спецификация, такая как DAL (например, GetByPK), или расширенная спецификация.
Внутри он работает с уровнем сопоставления данных (например, контекстом структуры сущностей и т. д.) Для выполнения фактической операции CRUD.
Что не означает шаблон репозитория: -
Кроме того, я видел, как люди часто путаются иметь отдельный метод Save в качестве примера реализации шаблона репозитория, помимо методов Insert / Update / Delete, которые фиксируют все изменения в памяти, выполняемые методами вставки / обновления / удаления в базу данных. У нас может быть метод Save определенно в репозитории, но репозиторий не обязан изолировать CUD в памяти (создание, обновление, удаление) и методы сохранения (которые выполняют фактическую операцию записи / изменения в базе данных), но Ответственность за шаблон Unit Of Work.
Надеюсь это поможет!
Репозиторий - это шаблон, это способ реализовать вещи стандартизованным способом для повторного использования кода, насколько это возможно.
Преимущество использования шаблона репозитория состоит в том, чтобы имитировать уровень доступа к данным, чтобы вы могли протестировать код бизнес-уровня, не вызывая код DAL. Есть и другие большие преимущества, но они кажутся мне очень важными.
Вы все еще можете имитировать DAL, это не обязательно должен быть репозиторий как таковой. Важным моментом является то, что какая бы стратегия доступа к данным вы ни использовали, она должна реализовывать интерфейс. Это позволит вам использовать контейнеры IoC, а также аккуратно тестировать бизнес-код без необходимости хранения данных.
Можно утверждать, что «репозиторий» - это определенный класс, а «DAL» - это весь уровень, состоящий из репозиториев, DTO, служебных классов и всего остального, что требуется.
Поздно на вечеринку, но почему T [], а не List <T> (или аналогичный)?