Решение по дизайну шаблона репозитория MVC

У меня есть приложение asp .net MVC, и я недавно начал реализовывать шаблон репозитория с уровнем проверки службы, как и this.

Я создавал по одному репозиторию / сервису для каждой модели, которую создаю. Это перебор? Вместо этого должен ли я создать один репозиторий / сервис для каждой логической области бизнеса, который предоставляет CRUD для многих различных моделей?

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


person bradjive    schedule 15.03.2010    source источник


Ответы (2)


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

Что это обозначает? Что ж, это во многом зависит от вашего приложения, но обычно есть объекты, которые естественным образом являются «родителями» других объектов или являются частью связанной транзакции.

Я думаю, что каноническим примером является система электронной коммерции, в которой у вас есть концепция заказа, а в заказе у вас есть строки заказа, каждая строка заказа - это какой-то продукт, количество и так далее.

В этом случае объект Order является одним из агрегированных корней системы, и создается OrderRepository.

В этом случае следует помнить, что существует некоторая связь (подразумеваемая или нет) между заказом и его строками заказа и так далее. Таким образом, части C-UD «CRUD» в репозитории, как правило, должны представлять собой только один метод каждая, и обычно должны просто принимать экземпляр этого совокупного корневого объекта и работать с ним (например, repo.Save (order)). Могут быть и другие возможные параметры, но это зависит от вашего impl.

Фактически, вы часто можете решить большую часть части C-UD с наследованием (то есть создать RepositoryBase, который реализует их, используя некоторую известную логику о том, что происходит для вашей конкретной схемы персистентности).

Итак, остается R-часть CRUD. В этом случае вы можете получить массу методов запроса (GetById; GetByName; GetByCustomerName и т. Д.), Если вы выберете путь метода запроса. Некоторые люди предпочитают, особенно для простых приложений, предоставлять интерфейс на основе linq (например, IQueryable GetAll ()), к которому затем могут применяться предложения Where. YMMV в зависимости от вашей базовой настойчивости, но это хороший шанс для простых приложений, особенно. если вы ожидаете, что ваш поставщик постоянства будет поддерживать linq напрямую.

Наконец, многие люди фактически отделяют часть запроса с помощью той или иной реализации шаблона разделения ответственности командного запроса, в котором говорится, что интерфейсы для сохранения и запросов должны быть разными. В этом случае у вас будет репо, в котором есть только базовые операции CRUD (GetById, GetAll, Save, Delete) и какой-то другой класс, который запрашивает вещи в зависимости от намерений вашего приложения.

Надеюсь, это поможет.

Павел

person Paul    schedule 15.03.2010
comment
Пол благодарит за подробный ответ. После долгих размышлений и прочтения я чувствую, что у вас есть один репозиторий / сервис для каждого совокупного корня. Вы также правы в отношении CRUD, по одному методу для C_UD и множеству методов R. В вашем примере с Order будет ли OrderRepository также местом для размещения методов R для OrderLines и OrderSubLines? - person bradjive; 17.03.2010
comment
Это хороший вопрос, и это зависит от обстоятельств. Означают ли строки заказа и подстроки что-нибудь полезное без связанного с ними порядка? Если да, то да, если нет, тогда все ваши запросы должны выполняться с заказами, и вы можете фильтровать дочерние коллекции, используя регулярные выражения LINQ над IEnumerables. - person Paul; 17.03.2010

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

В итоге я получил четыре репозитория и частичное расширение класса моей модели EF4 Entity Model для стандартных действий CRUD для дочерних сущностей (адреса, номера телефонов, коды состояния и т. Д.), Поэтому они были реализованы один раз и были доступны во всех репозиториях. Однако я все еще дорабатываю его по ходу дела, поэтому, возможно, я еще не нашел лучшего решения.

Я бы посоветовал попробовать это и посмотреть, подходит ли он, и посмотреть, подходит ли он. Обычно, если это не кажется правильным, все равно это неправильно.

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

person Moo    schedule 15.03.2010