Каковы лучшие практики для построения страницы Asp.net MVC, учитывающие параллелизм и эффективность? - PullRequest
8 голосов
/ 22 декабря 2011

Мне было трудно с чем-либо спорить в этой критике фреймворка ASP.net MVC для компоновки страниц.

http://www.matlus.com/problems-with-asp-net-mvc-framework-design/

В частности, эти пункты:

  • Нет доступа к просмотру или частичному просмотру экземпляров
  • ViewData - ваш свободно печатный носитель информации
  • Контроллер на самом деле не контролируется
  • дочерние действия не имеют смысла в контексте запроса
  • Представления связаны с контроллерами

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

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

Вот пример сценария приложения:

  1. 50% содержимого страницы является общим для всех страниц в приложении (верхний колонтитул, нижний колонтитул, меню и т. Д.)
  2. Ваше приложение может фактически состоять из нескольких областей, каждая со своими контроллерами и т. Д. Для самостоятельной разработки.
  3. Для ряда элементов страницы (меню, информация верхнего колонтитула, нижние колонтитулы, раскрытия), которые находятся в общем содержимом страницы, требуется один или несколько вызовов службы для заполнения данных для рендеринга.

Хорошо, так что в asp.net mvc3, допустим, вы решили, что хотите использовать общий макет Razor, который содержит 50% общей разметки пользовательского интерфейса. Это помогает с разделением проблем в том, что разработчикам приложений не нужно беспокоиться об общем пользовательском интерфейсе и они могут сосредоточиться на логике и взглядах, характерных для их области знаний.

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

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

Некоторые подходы к этой проблеме, которые я видел:

  • Сильно введите общий макет , который требует, чтобы все модели представлений были подклассами общего базового класса моделей. (но не существует общего решения для заполнения такой метамодели, и это ограничивает дизайн и делает модели огромными и более сложными для тестирования) Кроме того, популяция моделей по-прежнему приходится на каждый контроллер, нарушая принцип разделения проблем и принципа единой ответственности и усложняет модульное тестирование контроллеров, накапливая много дополнительной логики для заполнения метамодели в дополнение к информации о модели для конкретного вида.
  • Оставьте общий макет нетипизированным , чтобы вам не приходилось наследовать от общей базовой модели, но для этого необходимо использовать ViewData или ViewBag для передачи всех разрозненных моделей, которые нужны шаблону, так вы теряете сильные преимущества при наборе текста и в итоге получаете контракт на потерю данных. У вас все еще есть проблема отсутствия общего решения для заполнения метамодели и всего, что с этим связано.
  • Каждый контроллер должен иметь подкласс общего базового класса контроллера для поддержки общей компоновки и модели. Логика для построения общих аспектов метамодели идет здесь. Но это не всегда желаемое ограничение архитектуры или дизайна. Это, по крайней мере, решает проблемы разделения проблем.
  • Вместо метамодели используйте дочерние действия через RenderAction () в вашем общем макете для создания многократно используемых виджетов в стиле «портлетов», каждый из которых независимо знает, как построить свою модель данных, и предоставить ее своим Посмотреть. Это действительно хорошо для разделения проблем, но имеет свой собственный ряд недостатков: представления, эффективно выполняющие вызовы служб во время рендеринга через дочерние действия, дочерние действия полностью не знают о исходном контексте запроса, нарушают принцип DRY, поскольку каждое дочернее действие не знает о что было до того, чтобы каждый мог делать одни и те же вызовы службы снова и снова в одном и том же запросе http, и другие. Представьте себе 20-30 элементов страницы, которые все должны вызывать RenderAction () независимо ...

Существуют дополнительные случаи (некоторые встречаются также и в stackoverflow), когда существуют другие проблемы с RenderAction () в качестве решения. например тот факт, что выполнение нескольких вызовов RenderAction () в цикле приводит к последовательному выполнению всех этих методов контроллера. Нет возможности для параллелизма с RenderAction (). Связанные с I / O вызовы службы в каждом дочернем контроллере заставляют весь процесс рендеринга ожидать ввода-вывода. Контроллер знает только о своем непосредственном представлении и модели, и ничто не имеет полной картины того, что будет внутри представления для распараллеливания некоторых операций.

Автор вышеуказанной критики разработал другую модель пользовательского интерфейса поверх ASP.Net mvc под названием Quartz, которая позволяет контроллеру Бога иметь глубокие знания о представлениях и может передавать каждому из них модель представления, поэтому имеет возможность распараллелить Сервисные звонки в центральном месте, чтобы построить эти модели представления. Я не знаю, является ли это лучшим дизайном, обеспечивающим ловушки для преодоления проблем, но выглядит многообещающе.

Мой вопрос заключается в том, каков наилучший способ построения сложного приложения поверх ASP.Net MVC, которое чисто решает эти проблемы? Я думал о паре возможностей (хотя ни одна из них не может быть практичной в ASP.Net MVC - то есть TBD), но кто-то еще, должно быть, столкнулся с этим уже. Каковы шаблоны проектирования в ASP.Net MVC или что может привести к решению этой проблемы?

Ответы [ 2 ]

2 голосов
/ 22 декабря 2011

Лично я считаю, что преимущества использования дочерних действий через RenderAction перевешивают недостатки.

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

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

1 голос
/ 22 декабря 2011

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...