Просмотр и просмотр модуляризации модели в большом приложении ASP.NET Core

Создание всего уровня V* (представление, модель представления | контроллер) для корпоративного приложения или даже просто большого веб-приложения в целом может оказаться непосильной задачей. Если вы не будете осторожны, вы можете легко получить монолитный слой представления, который невозможно поддерживать. Мы все знакомы с этим монстром, с безудержной логикой в ​​​​шаблонах, встроенными сценариями и стилями. Мы собираемся оставить эти обсуждения на другой раз и основывать статью на нескольких рабочих предположениях/целях:

  • Отделить бизнес-логику от представления
  • Строгий тип каждого частичного представления
  • Отдельные встроенные статические файлы (JavaScript и CSS, я смотрю на вас)
  • Нет полной реализации Razor (нет страницы Razor со встроенными действиями, мы будем использовать контроллеры)
  • Механизм шаблонов Razor (мы будем использовать часть синтаксиса, предоставляемого Razor)
Quick Disclaimer: This implementation approach may not be beneficial to everyone,
and it’s dependent upon the technology you’re implementing. This is just the
approach that I took to make my application more modular, in a clean and concise
way that is easy to maintain and scale. With that being said, let’s continue!

Подход

Структура каталогов и организация являются очень важными составляющими модульной архитектуры V*. Для этого подхода я разбиваю представления на 2 основные категории:

  • Представления верхнего уровня
  • Частичные просмотры

Вы можете думать о представлении верхнего уровня как о драйвере для вашего представления; Он включает в себя все, что нужно для отображения одного полного раздела вашего сайта. Мы будем использовать пример панели мониторинга приложения для потоковой передачи музыки. Я создал простой визуальный макет, который вы можете увидеть ниже:
макет1.png

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

- Dashboard
- - - Playlist
- - - - - Song (a list of songs inside the Playlist view)
- - - PlaybackControls

Когда мы разбиваем его таким образом, мы начинаем видеть, как мы можем сделать Dashboard более модульным, поскольку все, что на самом деле делает Dashboard, — это предоставление контейнера, в котором живут другие частичные представления (аналогия с драйвером, которую мы использовали ранее).

Строго типизированные модели представлений

Следующим шагом будет строгая типизация каждого представления и частичного представления.

Зачем это делать?

Вы хотите строго типизировать свои представления и частичные представления, потому что это дает несколько конкретных преимуществ:

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

как нам это сделать?

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

- DashboardViewModel
- - - PlaylistViewModel
- - - - - SongViewModel
- - - PlaybackControlsViewModel
- DashboardView
- - - Playlist PartialView
- - - - - Song Partial View
- - - PlaybackControls Partial View

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

Quick Disclaimer: We are going to be operating under the assumption that we are already inheriting a parent Layout for our top level Views.

Ваш Макет.cshtml файл может выглядеть примерно так:

<!DOCTYPE html>
<html>
 <head>
  <!-- top level styles for all inherited views to use -->
  <link rel="stylesheet" href="~/path/to/useful/styles/useful.min.css" />
  
  <!-- additional view level styles -->
  @RenderSection("styles", required: false)
 </head>
 <body class="insert-your-useful-body-class">
  <div class="insert-your-useful-container-class">
   @await Component.InvokeAsync("Header")
   @await Component.InvokeAsync("Sidebar")
   
   <div class="insert-your-useful-content-wrapper-class">       
    <section class="insert-your-useful-content-class">
     <!-- Your Page Content Here -->
     @RenderBody()
    </section>
   </div>
   
   @await Component.InvokeAsync("Footer")
   @await Component.InvokeAsync("ControlSidebar")
  </div>
  
  <!-- top level scripts for all inherited views to use -->
  <script src="~/path/to/useful/scripts/useful.min.js"></script>
  <!-- additional view level scripts -->
  @RenderSection("scripts", required: false)
 </body>
</html>

Теперь, когда этот расширяемый макет настроен, вы можете настроить представление верхнего уровня. Ранее я упоминал, что представление верхнего уровня должно выступать в качестве драйвера для всех частей, необходимых для правильной работы раздела приложения. Для этого я рекомендую настроить родительский контейнер в представлении верхнего уровня, в этом примере DashBoardView.cshtml файл:

@model MusicStreamingApplication.Models.DashboardViewModel
@{
    // the overall layout to inherit
    Layout = "_Layout";
}
@section styles {
    <!-- any additional styles for Dashboard -->
}
<!-- all the partials Dashboard requires -->
<partial name="~/Views/Dashboard/Playlist.cshtml" for="Playlist" />
<partial name="~/Views/Dashboard/PlaybackControls.cshtml" for="PlaybackControls" />
@section scripts {
    <!-- any additional scripts for Dashboard -->
}

Обратите внимание, как мы передаем частичному представлению именно ту модель представления, которая ему нужна для работы и отображения правильных данных с помощью for атрибут. for является сокращением для @Model. поэтому результат использования for будет отображаться в @Model.Playlist для первого частичного.

Переходя к примеру с моделью, ваш DashboardViewModel.cs будет выглядеть примерно так:

using MusicStreamingApplication.Models.PlaylistViewModel;
using MusicStreamingApplication.Models.PlaybackControlsViewModel;
namespace MusicStreamingApplication.Models.DashboardViewModel
{
    public class DashboardViewModel
    {
        public RequestViewModel(){}
        
        public PlaylistViewModel Playlist { get; set; }
        public PlaybackControlsViewModel PlaybackControls { get; set; }
    }
}

Кроме того, вы можете начать видеть, как мы детализируем до точной детализации, необходимой для каждого частичного представления. PlaylistViewModel тогда будет SongViewModel и так далее.

Вывод

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

Похожие записи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *