ASP.NET MVC - я думаю, что я иду по этому поводу неправильно - PullRequest
2 голосов
/ 23 февраля 2011

Или я совсем не понимаю.

Я запустил приложение ASP.NET MVC, используя Controller -> ViewModel -> Service -> Repository pattern.

Должен ли каждый тип объекта (Клиент, Продукт, Категория, Счет-фактура и т. Д.) Иметь собственный репозиторий и сервис? Если да, то как вы объединяете общие предметы?

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

Поэтому я подумал, что мне нужен ShopController, у которого есть ShopViewModel, в котором могут быть категории, подкатегории, продукты и т. Д. Но проблема для меня в том, что он просто не очень хорошо работает.

Может быть, ASP.NET WebForms были для таких людей, как я:

Редактировать

Таким образом, совокупность будет состоять из:

Категория, Подкатегория, Продукт, ChildProduct, ProductReview с продуктом, являющимся совокупным корнем?

Затем в ViewModels вы получите доступ к Продукту, чтобы получить доступ к его дочерним продуктам, обзорам и т. Д.

Я использую Entity Framework 4, так как бы вы реализовали отложенную загрузку, используя шаблон хранилища / службы?

Ответы [ 3 ]

6 голосов
/ 23 февраля 2011

Должен ли каждый тип объекта (Клиент, Продукт, Категория, Счет-фактура и т. Д.) Иметь собственный репозиторий

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

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

и обслуживание?Если да, то как вы объединяете общие элементы?

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

Это может не иметь смысла

public void UpdateProduct(Product product)
{
  _repo.Update(product);
}

Но если у вас есть логика, этот уровень имеет смысл инкапсулироватьбизнес-правила для продуктов.

public void UpdateProduct(Product productToUpdate)
{
  //Perform some sort of business on the productToUpdate, raise domain events, ....
  _repo.Update(productToUpdate);
}

Поэтому я подумал, что мне нужен ShopController, у которого есть ShopViewModel, который может иметь категории, подкатегории, продукты и т. д. Но проблема для меня,в том, что он просто не выглядит хорошо.

Если домен очищен, модель представления имеет смысл

public ActionResult Index()
{
  ShopViewModel shopViewModel = new ShopViewModel();
  shopViewModel.Products = _productRepo.GetAll();
  //other stuff on the view model.
  return(shopViewModel);
}

Обновление

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

Если компания может жить сама по себе (например, вы редактируете, обновляете, удаляете компанию), я бы предложила, чтобы компания такжеСовокупный корень для вашего домена (у Клиента есть компания, а у компании есть список Клиентов).Однако, если Компания может быть получена только через Клиента, я бы отнес компанию к объекту ValueType / Value.В этом случае я бы создал метод в репозитории клиентов для извлечения всех имен компаний.

_repo.GetAllCompanyNames();
4 голосов
/ 23 февраля 2011

Хранилища необходимы, просто идите с ними. Они скрывают реализацию данных. При использовании с ORM вы можете в значительной степени забыть о основной активности БД (CRUD). Как правило, вы найдете карту 1: 1 между объектом и хранилищем, но ничто не мешает хранилищу возвращать все, что ему нравится. Как правило, хотя вы будете действовать на основе экземпляра. Создавайте не объектно-ориентированные репозитории для ваших запросов, которые естественно не вписываются в существующий.

Вы найдете много противоречивых аргументов в части «Службы», которую некоторые люди любят разделять между Службами домена (я бы назвал эти бизнес-правила, которые не совсем удобно вписываются в Базовый объект домена), и Службы приложений (логические группировки операций над объектами домена). На самом деле я выбрал один отдельный проект под названием [ProjectName] .Core.Operations, который находится в моей папке с решением [ProjectName] .Core. Основные + Операции = Домен.

Операция может быть чем-то, что возвращает DTO всей информации, которую требуется для представления, с помощью ряда вызовов репозитория и действий в Домене. Некоторые люди (включая меня) предпочитают полностью скрывать репозитории от Presentation и вместо этого использовать Operations (Services) как фасад для них. Просто идите с интуитивно понятным названием и не бойтесь, рефакторинг полезен. Ничего плохого в классе HomePageOperations с методом GetEveryThingINeedForTheHomepage возвращает класс ThingsINeedForTheHomePage.

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

Загрузите и посмотрите S # arp архитектура или Кто может мне помочь проекты. Последний действительно показывает хорошую архитектуру ИМХО.

И наконец, не забывайте, что одной из основных проблем уровней является возможность подключения / тестируемость, поэтому я советую вам разобраться с хорошим контейнером IoC (я фанат Castle.Windsor). И снова архитектура S # arp - хорошее место, чтобы узнать об этом.

1 голос
/ 23 февраля 2011

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

...