Каковы хорошие кандидаты на базовый класс контроллера в ASP.NET MVC?

Я видел много людей, которые говорили об использовании базовых контроллеров в своих проектах ASP.NET MVC. Типичные примеры, которые я видел, делают это для регистрации или, возможно, CRUD-леса. Каковы некоторые другие хорошие применения базового класса контроллера?

10 ответов

Решение

Нет хорошего использования базового класса контроллера.

Теперь выслушай меня.

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

  • Инфраструктура ведения журналов принадлежит конструктору и должна внедряться через структуру DI.

  • Строительные леса CRUD должны обрабатываться генерацией кода или пользовательским поставщиком ModelMetadata.

  • Глобальная обработка исключений должна обрабатываться пользовательским ActionInvoker.

  • Данные глобального просмотра и авторизация должны обрабатываться фильтрами действий. Еще проще с глобальными фильтрами действий в MVC3.

  • Константы могут быть в другом классе / файле с именем ApplicationConstants или чем-то еще.

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

Я почти уверен, что нет ни одной проблемы, которую вы не можете решить с помощью другого хука расширяемости, кроме базового класса контроллера. Не принимайте наименьшую форму сцепления (наследования), если нет существенной причины производительности и вы не нарушаете Лискова. Я бы предпочел потратить < 1 секунду, чтобы набрать свойство 20 раз на моих контроллерах, как public ILogger Logger { get; set; } чем ввести жесткую связь, которая влияет на применение гораздо более значительными способами.

Даже что-то вроде userId или многопользовательского ключа может идти в ControllerFactory вместо базового контроллера. Стоимость подключения базового класса контроллеров просто не стоит.

Мне нравится использовать базовый контроллер для авторизации.

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

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

Я использую его для доступа к сеансу, данным приложения и т. Д.

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

По сути, я использую это для вещей, которые я повторяю много

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

Я использовал базовый контроллер во многих моих проектах и ​​работал фантастически. Я в основном использовал для

  • Регистрация исключений
  • Уведомление (успех, ошибка, добавление..)
  • Вызов HTTP404 обработки ошибок

Я использовал общий базовый класс контроллера для обработки:

  • я создал BaseCRUDController<Key,Model> который требовал ICRUDService<TModel> Объект в качестве параметра конструктора, поэтому базовый класс будет обрабатывать Create / Edit / Delete. и обязательно в виртуальном режиме для обработки в пользовательских ситуациях
  • ICRUDService<TModel> имеет такие методы, как Save / Update / Delete / Find / ResetChache /..., и я реализую его для каждого репозитория, который я создаю, чтобы добавить к нему больше функциональности.
  • используя эту структуру, я мог бы добавить некоторые общие функции, такие как PagedList / AutoComplete / ResetCache / IncOrder & DecOrder (если модель IOrderable)
  • Обработка сообщений обошибках / уведомлений: часть макета с @TempData["MHError"] код и свойство в базовом контроллере, как

    общедоступная ошибка уведомления { set { TempData["MHError"] = значение; } get { return (Notification) TempData.Peek("MHError"); } }

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

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

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

Мы используем BaseController для двух вещей:

  1. Атрибуты, которые должны применяться ко всем контроллерам.
  2. Переопределение перенаправления, которое защищает от атак открытого перенаправления, проверяя, является ли URL перенаправления локальным URL. Таким образом, все контроллеры, вызывающие Redirect, защищены.

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

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

Мы использовали базовый контроллер:

  1. преодолеть .User свойство, потому что мы используем наш собственный объект User, который должен иметь наши собственные настраиваемые свойства.
  2. добавить глобальный OnActionExecuted логики и добавить несколько глобальных фильтров действий
Другие вопросы по тегам