Абстрактные и динамически сгенерированные контроллеры в ASP.NET | Статья в журнале «Молодой ученый»

Отправьте статью сегодня! Журнал выйдет 26 октября, печатный экземпляр отправим 30 октября.

Опубликовать статью в журнале

Автор:

Рубрика: Информационные технологии

Опубликовано в Молодой учёный №24 (314) июнь 2020 г.

Дата публикации: 11.06.2020

Статья просмотрена: 120 раз

Библиографическое описание:

Асылгареев, Р. Ф. Абстрактные и динамически сгенерированные контроллеры в ASP.NET / Р. Ф. Асылгареев. — Текст : непосредственный // Молодой ученый. — 2020. — № 24 (314). — С. 47-52. — URL: https://moluch.ru/archive/314/71556/ (дата обращения: 16.10.2024).



В данной статье будет рассмотрен подход автоматически сгенерированных контроллеров в одной из самых популярных технологий для написания веб-сайтов — ASP.NET Core MVC.

Ключевые слова: разработка ПО, C#, ASP.NET, MVC, контроллеры, метапрограммирование.

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

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

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

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

MVC— контроллеры.

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

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

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

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

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

Давайте рассмотрим две тестовые сущности, с которыми мы будем работать:

https://lh4.googleusercontent.com/tFjvNRHiLdHthPNOOIOe5P9ARN7dMbbEYC_FCiBeeFcRlUaof9-aUm4ZyX_NnKoecxRKXM5d2-wJoRvDhPpIavf2-BvxrueBJrC_gimCJ2o-GRBx_eWl7GgIrjvdsgDBBU0PXkCu

Рис. 1. Демонстрационные сущности

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

Универсальный сервис хранения данных, придуманный для данной статьи, очень прост и основан на словаре в памяти. Частично сервис представляет из себя реализацию паттерна “Репозиторий” и предоставляет только операции чтения и сохранения:

https://lh6.googleusercontent.com/9O2IbdHw1OAqa8loPmtP-VNliQjk9qo5YS_9cRUyGIInYa-LJtq3VMHpKzy83w7tla3v-hDA7lZvY-xMqVg--yocs_3AzKp2YxI_MDR6rPK1-pWAxjTXALhoNKz4TCMqGmtD19rO

Рис. 2. Универсальный сервис хранения данных

Наконец, вооружившись всем этим, мы можем приступить к рассмотрению видов универсальных контроллеров.

Абстрактный контроллер

Абстрактные контроллеры не поддерживаются из коробки по ASP.NET ядро MVC. Тем не менее, нетрудно представить, как будет выглядеть такой контроллер:

https://lh5.googleusercontent.com/tUh3WzaNxdJ8Lr-yLUU-FNgid6P4bclLvT17KpD4IfcQJiAfka32uOD_ukiovAZUTeTEqBsLPz_MwfLgRunTTgwaM9n2l2mAY7KWQNzXrdqswoxqXTSq2oOWSBlu_yrk62AHqKZU

Рис. 3. Реализация абстрактного контроллера

Здесь не так уж много нужно обсуждать, поскольку код говорит сам за себя — мы просто выставляем операции из нашего общего хранилища как операции GET/POST. Мы могли бы пойти дальше, добавив PUT, DELETE или что-то еще, но фактические детали реализации здесь имеют второстепенное значение.

Как уже упоминалось, ASP.NET ядро не будет рассматривать BaseController как допустимый контроллер. Причина вполне очевидна — он не знал бы, что положить в букву «Т«. [3]

Давайте теперь рассмотрим, как мы могли бы решить это проблему.

Подход 1. Наследование от абстрактного контроллера.

Самым простым решением было бы сделать дочерние контроллеры, которые наследуются от BaseController и заполняют параметр T. Таким образом дочерние контроллеры могут быть обнаружены и использованы в MVC — структуре без каких-либо проблем.

https://lh3.googleusercontent.com/zL3sLpGX4UNYsx_l9-rZzcDECKqg8ShowLE_W0CPEe96VTxB8fEZDL1bQ1c3jweQiZ12DoVcKuKTHRhs2T81p50gWwoxXRkZfqr_hdTe36U6Xe62583uAUNehl-Pi9ngMaeHcoNX

Рис. 4. Дочерние контроллеры, реализующие GenericController

Код, показанный выше сразу же работает, и никакие дополнительные настройки или пользовательские расширения не требуются. Имена наших контроллеров Book и Album вставляются в шаблон маршрута из базового класса [Route(“api/ [controller]”)], и все определенные операции GET/POST доступны автоматически.

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

Подход 2. Динамические контроллеры

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

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

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

Чтобы это реализовать, нам нужно будет ввести дополнительный декоратор. Для этого введем атрибут GeneratedControllerAttribute.

Он будет использоваться нами для обозначения типов, которые мы хотели бы использовать совместно с BaseController в качестве маршрутов HTTP.

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

https://lh6.googleusercontent.com/o3QUcGGXLnrZzQIsrl-W9Fd7s7pu4e0dshVU8LqolopSyb0B7t6oDczq-qwN3viwZOC2A0ATMkucRuVVAt77y6O9wXhnNkZCI1Y0VLIyxS_JAMY6I2rokq853pSgB2CMuQjvKTZw

Рис. 5. Атрибут GeneratedControllerAttribute

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

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

https://lh5.googleusercontent.com/WjcC_cil144XXNmtIOcyREYtYLzs3uXtJe4qctHdtH-UFgNOgE0UE0RyW0d2DSpm7NHrJmUmPg8lasQKF7G4OM7tnqIEWcqYAdG-b6GG1i2ZQfMacUnf8f8oKzd9C33XjfLkMj0O

Рис. 6. Реализация GenericTypeControllerFeatureProvider

Нам все еще нужно обрабатывать маршруты, которые мы определили как часть нашего GeneratedControllerAttribute. Мы можем сделать это с помощью настраиваемой конвенции MVC [2].

В нашей конвенции мы возьмем шаблон маршрута из атрибута и введем его в контроллер, как если бы это был встроенный маршрут атрибута (эквивалентно использованию атрибута [Route(...)] на контроллере).

https://lh6.googleusercontent.com/oryHi3C8EEkiYl7dK-x9HgjA9gTffRsKftqeG7ibA5sw1_J3Oi3odf4SoQbNrSRXdHEs46rxGia2-dxa0fv_iUYFLoDTK6kAFZANDwtF_VECvlPKq_M3edNJPINvvDudlGPF84wn

Рис. 7. Настраиваемая конвенция MVC

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

Обе пользовательские функции: GenericTypeControllerFeatureProvider и GenericControllerRouteConvention — должны быть добавлены в сборку MVC при запуске. Это делается как часть класса Startup, как только мы вызываем AddMvc() [1].

https://lh6.googleusercontent.com/8T273dggrT4RV-cJGRqpExf83q_JSNLboY0EvfgWESE5FxAJtlYvvFp2yiIWDrbQKMmlIaYy9Syk68t9HT6sevydn5ozeB4FxI8Rs76WhcwGKu2QC85_4e7Mz5VZoB-EFPx_WVzb

Рис. 8. Регистрация GenericTypeControllerFeatureProvider и GenericControllerRouteConvention

Наконец, мы должны добавить атрибут для сущностей:

https://lh5.googleusercontent.com/u-RE2NSctb_OHr7eizdhVlDqDpuRBLU2BFRenQzlYmwwMiQharhM6E6EijFBSeNPS4CB9X7_hxYO0hUt5bpenOR2H9ztiSziDO3M8wB9lFpA2798fza9-TcT5lrYo96tINOy7kp4

Рис. 9. Пример использования реализованного функционала

Код показанный выше заставит работать эти классы как объекты контроллеров. Теперь мы можем добавить сколько угодно типов DTO, декорировать их атрибутом GeneratedControllerAttribute и использовать их как общедоступный вызываемый HTTP маршрут.

Литература:

  1. Рихтер CLR via C#. Программирование на платформе Microsoft.NET Framework 2.0 на языке C# / Рихтер, Джефри. — М.: Питер, 2012. — 656 c.
  2. Робинсон, С. C# для профессионалов / С. Робинсон, О. Корнес, Д. Глинн, и др. — М.: ЛОРИ, 2018. — 779 c.
  3. Альфред, В. Ахо Компиляторы. Принципы, технологии и инструментарий / Альфред В. Ахо и др. — М.: Вильямс, 2015. — 266 c.
Основные термины (генерируются автоматически): MVC, контроллер, HTTP, GET, POST, абстрактный контроллер, тип, API, DELETE, универсальный сервис хранения данных.


Ключевые слова

MVC, ASP.NET, контроллеры, C#, разработка ПО, метапрограммирование

Похожие статьи

Технология ASP.NET MVC

В статье рассматривается проектирование архитектуры приложений ASP.NET MVC. Авторы описывают теоретические основы ASP.NET MVC, которые необходимы для разработки web-приложений платформы.NET Framework.

Использование сервиса API SendGrid для реализации отправки Email-сообщений в проекте ASP.NET Core

В данной статье рассмотрено использование Email-рассылки при помощи API SendGrid в проекте ASP.NET Core.

Разработка алгоритма валидации форм на клиентской стороне для передачи данных

В данной статье рассмотрены методы и алгоритмы функционирования систем клиент-серверной архитектуры для передачи данных с помощью технологий программных инструментов: HTML, CSS, Javascript.

Использование двухфакторной аутентификации в проекте ASP.NET Core

Данная статья рассматривает процесс настройки двухфакторной аутентификации в проектах ASP.NET Core.

Автоматическая поддержка документации Asp.Net Core и Angular веб-приложений

В данной статье рассматривается автоматизация генерации и сопровождения документации Asp.Net Core и Angular приложения, с автоматической публикацией в GitLab.

Востребованные backend-технологии для разработки программного продукта

В статье авторы определяют востребованные backend-технологии для разработки программного продукта.

Рассмотрение декларативного подхода к разработке интерфейсов мобильных приложений для Android

В данной статье рассматриваются императивный и декларативный подходы к разработке интерфейсов, анализируются преимущества и недостатки библиотеки Jetpack Compose.

Защита веб-приложения на фреймворке Django

При проектировании веб-приложения важна защита пользовательских данных. В данной статье рассмотрим основные типы атак и методы защиты на фреймворке Django.

Сравнительный анализ библиотек языка PHP для формирования документов веб- сервисами

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

Работа с элементами GUI на примере приложения с использованием кроссплатформенного фреймворка Qt

В статье подробно разобран код приложения, написанного с использованием кроссплатформенного фреймворка Qt основанного на языке C++. Приложение Dynamic Layouts является одним из примеров, входящих в пакет Qt Creator. На примере данного приложения расс...

Похожие статьи

Технология ASP.NET MVC

В статье рассматривается проектирование архитектуры приложений ASP.NET MVC. Авторы описывают теоретические основы ASP.NET MVC, которые необходимы для разработки web-приложений платформы.NET Framework.

Использование сервиса API SendGrid для реализации отправки Email-сообщений в проекте ASP.NET Core

В данной статье рассмотрено использование Email-рассылки при помощи API SendGrid в проекте ASP.NET Core.

Разработка алгоритма валидации форм на клиентской стороне для передачи данных

В данной статье рассмотрены методы и алгоритмы функционирования систем клиент-серверной архитектуры для передачи данных с помощью технологий программных инструментов: HTML, CSS, Javascript.

Использование двухфакторной аутентификации в проекте ASP.NET Core

Данная статья рассматривает процесс настройки двухфакторной аутентификации в проектах ASP.NET Core.

Автоматическая поддержка документации Asp.Net Core и Angular веб-приложений

В данной статье рассматривается автоматизация генерации и сопровождения документации Asp.Net Core и Angular приложения, с автоматической публикацией в GitLab.

Востребованные backend-технологии для разработки программного продукта

В статье авторы определяют востребованные backend-технологии для разработки программного продукта.

Рассмотрение декларативного подхода к разработке интерфейсов мобильных приложений для Android

В данной статье рассматриваются императивный и декларативный подходы к разработке интерфейсов, анализируются преимущества и недостатки библиотеки Jetpack Compose.

Защита веб-приложения на фреймворке Django

При проектировании веб-приложения важна защита пользовательских данных. В данной статье рассмотрим основные типы атак и методы защиты на фреймворке Django.

Сравнительный анализ библиотек языка PHP для формирования документов веб- сервисами

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

Работа с элементами GUI на примере приложения с использованием кроссплатформенного фреймворка Qt

В статье подробно разобран код приложения, написанного с использованием кроссплатформенного фреймворка Qt основанного на языке C++. Приложение Dynamic Layouts является одним из примеров, входящих в пакет Qt Creator. На примере данного приложения расс...

Задать вопрос