Правильно ли структурировано мое приложение ASP.NET MVC? - PullRequest
5 голосов
/ 20 сентября 2009

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

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

Для метода 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();
}

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

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

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

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

Ответы [ 2 ]

4 голосов
/ 01 октября 2009

_someRepositoryOrService.Add (id, classA, classB);

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

public void Add (int id, ClassA classA, ClassB classB)

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

  1. отображение картографических данных на объекты
  2. сохранить в хранилище

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

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

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

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

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

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

4 голосов
/ 20 сентября 2009

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

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

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

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

...