Книга: ASP.NET MVC Framework
Фабрика контроллеров
Фабрика контроллеров
После того как внутренний механизм MVC получит запрос, обработает таблицу маршрутизации и подберет необходимый маршрут, в дело вступает фабрика контроллеров. По умолчанию создается и используется экземпляр фабрики контроллеров типа DefaultFactoryController
. Для реализации своего варианта поведения фабрики контроллеров разработчик может реализовать свой класс, наследующий класс DefaultFactoryController
.
Фабрика контроллеров — это механизм, созданный с одной целью — создавать экземпляры контроллеров. В ASP.NET MVC фабрика контроллеров — это один из механизмов, который позволяет настроить поведение механизма MVC под себя, расширить функционал, предоставить разработчику возможность гибкой настройки действия MVC.
Фабрика контроллеров в ASP.NET реализует интерфейс IControllerFactory
, который содержит всего два метода:
public interface IControllerFactory {
IController CreateController(RequestContext requestContext,
string controllerName);
void ReleaseController(IController controller);
}
Здесь CreateController
должен создавать экземпляр контроллера, а ReleaseController
— разрушать его или проводить какие-то другие действия после завершения работы контроллера. Вы можете создать свою фабрику контроллеров, реализовав этот интерфейс. Но более простым способом расширения фабрики является ее реализация с помощью наследования от класса DefaultFactoryController
.
Для примера рассмотрим такую, вполне возможную задачу, решить которую позволит фабрика контроллеров:
? необходимо создать механизм, который позволит ограничивать создание определенных контроллеров на основе "черного списка";
? решение на базе маршрутов таблицы маршрутизации не может нас удовлетворить, поскольку создание маршрутов производится через исполняемый код, который по каким-то причинам не может быть модифицирован для загрузки маршрутов из внешнего источника;
? решение на базе маршрутов не может нас удовлетворить в связи с тем, что у нас много универсальных маршрутов, которые затрагивают сразу много контроллеров;
? требуется возможность работать с "черным списком" в виде редактирования определенного файла для возможности разделения и предоставления прав к нему.
Согласно этим требованиям создадим фабрику контроллеров, которая позволит нам ограничивать выполнение контроллеров по их именам через XML-файл "черного списка". Вот пример такого файла:
<?xml version="1.0" encoding="utf-8" ?>
<blacklist>
<item typeName="AccountController" />
<item typeName="AdminController" />
</blacklist>
Как можно увидеть, данным файлом мы хотели бы заблокировать выполнение контроллеров AccountController
и AdminController
.
Реализуем фабрику контроллеров, наследуя класс DefaultFactoryController
:
public class ControllerFactory : DefaultControllerFactory {
protected override IController
GetControllerInstance(Type controllerType)
{
if (controllerType == null)
return base.GetControllerInstance(controllerType);
XmlDocument xdoc = new XmlDocument();
string blacklistPath =
HttpContext.Current.Server.MapPath("~/blacklist.xml");
xdoc.Load(blacklistPath);
XmlNodeList nodes = xdoc.GetElementsByTagName("blacklist");
foreach (XmlNode node in nodes[0].ChildNodes)
{
if (node.Attributes["typeName"].Value == controllerType.Name)
throw new HttpException(404, "Страница не найдена");
}
return base.GetControllerInstance(controllerType);
}
}
Как вы можете видеть, единственным методом нашего класса является реализация перегруженного метода GetControllerInstance
класса DefaultControllerFactory
. В нем мы реализуем следующую последовательность действий:
1. Проверяем, не передается ли в фабрику контроллера типа контроллера в виде null, если это так, то завершаем выполнение вызовом базового метода для выполнения действия по умолчанию.
2. Загружаем наш XML-файл с "черным списком" и ищем в нем имя типа контроллера, который запрошен для создания.
3. Если в "черном списке" существует запись о блокировании данного контроллера, то возвращаем ответ на запрос в виде 404 ошибки HTTP "Страница не найдена".
4. Если контроллер отсутствует в "черном списке", то мы выполняем базовое действие по умолчанию для поиска и создания необходимого контроллера.
Для того чтобы наш код заработал, мы должны зарегистрировать нашу фабрику контроллеров. Функцию регистрации выполняет метод SetControllerFactory
класса controllerBuilder
. Добавим его вызов в файл Global.asax:
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
ControllerBuilder.Current.SetControllerFactory( new ControllerFactory());
}
После этого попробуем запустить наше приложение. Главная страница запустится нормально, т. к. она создается с помощью контроллера HomeController
. Но если мы попробуем перейти на страницу входа, регистрации или административную страницу, то увидим стандартное сообщение браузера о том, что страница не была найдена.
Другим, пожалуй, самым распространенным вариантом использования фабрики контроллеров является реализация архитектурного паттерна Инверсия контроля (Inversion of Control), который в данном применении позволяет в приложении уменьшить зависимость и ослабить связи между контроллерами. Для реализации такого механизма используются сторонние библиотеки, вроде Unity Application Blocks от Microsoft, Spring.NET или Ninject.
- 1.13. Управление массивом контроллеров видов, относящихся к навигационному контроллеру
- 1.16. Представление контроллеров, управляющих несколькими видами, с помощью UITabBarController
- 4.1. Аппаратные средства микроконтроллеров семейства 68HC12
- Глава 3 ОСНОВЫ ПРОГРАММИРОВАНИЯ МИКРОКОНТРОЛЛЕРОВ НА СИ
- Программная фабрика: дайте мне модель, и я сдвину Землю
- Отказ от полуфабрикатов
- Фабрика звезд
- Глава 1. Реализация контроллеров и видов
- Назначение контроллеров Обзор контроллеров в ASP.NET MVC
- Советы по использованию контроллеров
- Архитектура контроллеров
- Наследование контроллеров