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

Шаблон хранилища, POCO и бизнес-объекты

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

Мой вопрос в том, что, как правило, я добавляю и сохраняю методы в своих бизнес-объектах. Скажем, я пишу сайт Q/A, и у меня есть следующие сущности: вопросы, ответы и комментарии. Если бы я хотел использовать шаблон репозитория, мне в основном нужно сохранить только свойства в моих бизнес-сущностях (например, вопрос) и перенести мои операции в класс репозитория (например, QuestionRepository), правильно? Если это так, означает ли POCO бизнес-объект с только свойствами?

Я использую Entity Framework 4.0, который создал мои сущности в коде edmx. Если бы я хотел использовать шаблон репозитория с этим, нет необходимости писать мои собственные бизнес-сущности (вопрос, ответ и т.д.), Так как они уже созданы EF, правильно? Все, что мне нужно, это репозиторий, чтобы делать CRUD? И у меня будет три хранилища для этого примера, по одному для каждого объекта?

4b9b3361

Ответ 1

У ваших объектов POCO все еще будут методы для них для операций, но эти операции будут относиться к проблемам бизнеса предприятия, а не к проблемам сохранения (CRUD). Если в вашей организации нет бизнес-операций, тогда да, они будут просто свойствами.

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

У вас может быть один класс репозитория или репозиторий для каждого объекта.

Ответ 2

Сначала рассмотрим шаблон проекта MVC проекта Asp.net

Я должен сказать, что существует небольшое недоразумение с шаблоном проекта Visual Studio Asp.net MVC. И это папка Model. Люди, не зная шаблон MVC, автоматически связывают это с моделью данных, а не с моделью приложения/презентации MVC. Это хорошо для простых приложений, где мы не различаем их, но не для чего-либо еще.

Продолжим мой ответ

Когда я пишу приложения бизнес-уровня, я разделяю свое решение на 4 проекта (по крайней мере):

  • уровень представления - приложение ASP.NET ASP.NET, но я удаляю папку Model и имею все мои представления как сильные виды типов, чтобы избежать как можно большего количества магических строк
  • уровень обслуживания - процессы бизнес-логики
  • уровень данных - модель данных, т.е. EF4 и, которые обращаются к этой модели
  • object tier - этот проект фактически имеет POCOs, которые используются для межуровневой связи и любые интерфейсы, используемые различными уровнями (думаю, IoC).

Мой процесс запроса обычно выглядит очень чистым и работает таким образом:

  • Когда выполняется запрос, мое действие контроллера MVC-контроллера Asp.net проверяет данные (объекты POCO), делает все необходимое для уровня представления перед вызовом в службы.
  • Вызывается служба, которая выполняет любую логику бизнес-процесса и обычно вызывает репозиторий, чтобы что-то делать с данными.
  • Репозиторий манипулирует данными в модели данных, а затем создает POCO из результатов, которые будут возвращены на уровень обслуживания.
  • Сервисный уровень получает POCOs делает дополнительную логику, если это необходимо, и возвращает их обратно в презентацию.
  • Презентация (контроллер) решает, какое представление отображать и предоставляет модель для этого конкретного представления и возвращает его. Конечно, вместо представления это может быть и любой другой результат.

Преимущество использования отдельных классов моделей MVC в проекте Objects (вы не могли поместить их в папку Model из-за круговой ссылки на проект) заключается в том, что у меня могут быть классы с оптимизированной презентацией. Или лучше сказал: У меня есть ориентированный на бизнес-процесс интерфейс, а не центр данных.

Объясните это с помощью примера: возьмите, например, просмотр регистрации пользователя. Он не может быть строго типизирован для модели данных User. Зачем? Потому что он имеет два входа для пароля. Таким образом, у меня может быть класс модели приложения/презентации под названием UserRegistration, хотя в модели данных ничего подобного нет. Его валидация работает совершенно по-другому по сравнению с объектом модели данных User. Если бы у меня была моя регистрация пользователя без сильного типа, мне пришлось бы выполнить действие моего контроллера со всеми параметрами каждого отдельного поля. Они не будут автоматически проверены, что означало бы, что я могу иметь большую поверхность ошибок. Кто-то может спешить писать код, но забыть о некоторых аспектах проверки.

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

Ответ 3

Я был в очень похожем месте, как OP когда-то, поэтому я расскажу о Роберте с некоторым кодом того, как я структурировал приложение asp.net mvc после изучения шаблона репозитория.

Итак, ваш проект QandA

У вас будет проект библиотеки классов с именем QandA.data, здесь вы создадите файл edmx и все классы фреймворка. Затем у вас есть репозиторий для каждого объекта вроде этого:

public interface IRepository<T>
{
    T Save(T entity);
    void Delete(T entity);
    IQueryable<T> GetAll();
    T GetById(int id);
}

У вас может быть либо factory, либо использовать Injection Dependency для получения фактически репозиториев. Итак:

class QuestionRepo : IRepository<Question>
{
 //call xxxEntites and get/save/delete yourentities here.
}
static class RepositoryFactory
{
 public static IRepository<Question> GetQuestionRepo()
 {
  return new QuestionRepo();
 }
}

Затем в коде вызова (в вашем проекте asp.net) у вас есть

IRepository<Question> qRepo = RepositoryFactory.GetQuestionRepo();
Question q =  qRepo.GetById(1);

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

static class RepositoryFactory
{
 public static IRepository<Question> GetQuestionRepo()
 {
  return new FakeQuestionRepo();
  //create your own fake repo with some fixed fake data.
 }
}

Теперь вы вызываете код, который не изменяется вообще, если вы бросаете его поддельным или реальным репозиторием.

Кроме того, о чем говорит Робер в своем вопросе, есть ViewModel. Таким образом, вы не сделали бы строго типизированную страницу типа Вопрос. Таким образом, у вас есть

class QuestionForm
{
 public string Title
 public string QuestionContent
}

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

[HttpPost]
public ActionResult Create(QuestionForm quesfrm)
{
 IRepository<Question> qRepo = RepositoryFactory.GetQuestionRepo();
 Question ques = new Question {
 AskedDate = DateTime.Now,
 Title = quesfrm.Title,
 Content = QuestionContent
 }
  qRepo.Save(ques);
}

Роберт упоминает одну из причин, почему вы это сделаете, есть еще несколько причин, и вы можете больше узнать о моделях просмотра на SO. Также проверьте код nerddinner

Возможно, вы захотите увидеть эти вопросы SO:
Если репозитории реализуют IQueryable <T> ?
Образец репозитория: один класс репозитория для каждого объекта?

Я надеюсь, что это помогло.