Правильно ли структурировано мое приложение ASP.NET MVC?

StackOverflow https://stackoverflow.com/questions/1450209

Вопрос

Я просматривал учебные пособия (в частности, те, которые используют Linq-To-Entities), и я понимаю основные концепции, однако некоторые вещи вызывают у меня проблемы.

Учебные пособия обычно включают только простые модели и формы, которые используют только базовые инструкции create, update и delete.Мои немного сложнее, и я не уверен, что делаю это правильно, потому что, когда приходит время обрабатывать взаимосвязи полудюжины объектов базы данных, учебные пособия перестают помогать.

Для метода post обычный способ выполнения операций CRUD

entities.AddToTableSet(myClass);
entities.SaveChanges();

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

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Add(int id, [Bind(Exclude = "Id")] ClassA classA,
                        [Bind(Exclude = "Id")]ClassB classB)
{
   // Validation occurs here

   if(!ModelState.IsValid)
      return View();

   try
   {
      _someRepositoryOrService.Add(id, classA, classB);
      return RedirectToAction("Index", new { id = id });
   }
   catch(Exception ex)
   {
      // Logging and exception handling occurs here
   }
}


public void Add(int id, ClassA classA, ClassB classB)
{
    EntityA eA = new EntityA
    {
        // Set a bunch of properties using the two classes and
        // whatever queries are needed
    };

    EntityB eB = new EntityB
    {
        // Set a bunch of properties using the two classes and
        // whatever queries are needed
    };

    _entity.AddToEntityASet(eA);
    _entity.AddToEntityBSet(eB);
    _entity.SaveChanges();
}

Правильно ли я справляюсь с этим или я порчу фреймворк?На самом деле я никогда не использую объект entity напрямую, всякий раз, когда я запрашиваю его, я помещаю нужную мне информацию в DTO и основываю на этом свои взгляды.То же самое относится и к сотворению мира.Разрешено ли это, или мое уклонение от использования сущностей напрямую противоречит цели использования фреймворка?

Редактировать:Я также обеспокоен этим подходом, потому что он требует пустых конструкторов для правильного выполнения запросов LINQ из-за этого сообщения об ошибке:

В LINQ для Entities поддерживаются только конструкторы без параметров и инициализаторы.

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

Это было полезно?

Решение

_someRepositoryOrService.Добавить (идентификатор, ClassA, ClassB);

Я бы сказал, что вы связываете свои репозитории со слоем представления.Этого не должно быть.Ваши репозитории должны работать только с сущностями.Затем обратите внимание, как ваш метод Добавления

добавить общедоступную пустоту(идентификатор int, ClassA ClassA, ClassB ClassB)

нарушает разделение интересов (SoC).Он выполняет две задачи:

  1. отображение данных на карте в виде объектов
  2. сохранить в репозиторий

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

Проверьте также этот превосходный Публикация автор Джимми Богард (соавтор книги ASP.NET MVC в действии) о ViewModels.Это может помочь вам автоматизировать сопоставление.Это также предлагает обратную технику - заставить ваши контроллеры работать с сущностями, а не с ViewModels!Пользовательские фильтры действий и привязки моделей на самом деле являются ключом к устранению рутины, которая на самом деле не принадлежит контроллерам, а скорее является деталью инфраструктуры между представлением и контроллером.Например, здесьвот как я автоматизирую повторную выдачу сущностей. Здесьвот как я вижу, что должны делать контроллеры.

Цель здесь состоит в том, чтобы заставить контроллеры сосредоточиться на управлении бизнес-логикой, отложив в сторону все технические детали, которые не относятся к вашему бизнесу.Это технические ограничения, о которых вы говорите в этом вопросе, и вы позволяете им просачиваться в ваш код.Но вы можете использовать инструменты MVC для перехода на уровень инфраструктуры them.

Обновить:Нет, репозитории не должны обрабатывать данные формы, это то, что я подразумеваю под "связью с презентацией".Да, репозитории находятся в контроллере, но они не работают с данными формы.Вы можете (хотя и не должны) заставить форму работать с "данными репозиториев", т.е.сущности - и это то, что делает большинство примеров, напримерNerdDinner - но никак не наоборот.Это связано с общим эмпирическим правилом - более высокие уровни могут быть соединены с более низкими (представление в сочетании с репозиториями и сущностями), но никогда низкий уровень не должен быть соединен с более высокими (сущности зависят от репозиториев, репозитории зависят от модели формы и т.д.).

Первый шаг должен быть выполнен в репозитории, это верно - за исключением того, что сопоставление из ClassX в EntityX не относится к этому шагу.Это проблема картографирования - инфраструктура.Смотрите, например это вопрос о сопоставлении, но обычно, если у вас есть два уровня (пользовательский интерфейс и репозитории), они не должны заботиться о сопоставлении - служба / помощник картографа должна.Помимо блога Джимми, вы также можете прочитать ASP.NET MVC в действии или просто посмотреть на их Сервер Кодек - Кэмпов о том, как они выполняют сопоставление с интерфейсами IEntityMapper, передаваемыми конструкторам контроллеров (обратите внимание, что это более ручной и менее трудоемкий подход, чем AutoMapper Джимми Богарда).

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

Другие советы

Я бы сказал, что использование DTO и обертывание Entity Framework вашими собственными методами доступа к данным и бизнес-уровнем - отличный способ.В конечном итоге вы можете написать много кода, но это лучшая архитектура, чем притворяться, что сгенерированный Entity Framework код является вашим бизнес-уровнем.

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

Кажется, что вы на правильном пути, продолжайте идти.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top