Пользовательский контроллер Factory, проблемы с инжекцией зависимостей/структуры с помощью ASP.NET MVC
Недавно я попытался реализовать инъекцию зависимостей с помощью StructureMap. Мне удалось полностью следовать примеру, но я сталкиваюсь с созданным исключением каждый раз, когда я пытаюсь запустить приложение. Вот некоторые фрагменты кода моего контроллера factory.
public class StructureMapControllerFactory : DefaultControllerFactory
{
protected override IController GetControllerInstance(Type controllerType)
{
if (controllerType == null)
throw new ArgumentNullException("controllerType");
return ObjectFactory.GetInstance(controllerType) as Controller;
}
}
My Global.asax вызывает статический класс BootStrapper, который регистрирует все мои зависимости, но похоже, что StructureMapControllerFactory GetControllerInstance вызывается дважды. В первый раз, когда он вызвал, передается правильный тип controllerType, но он всегда равен нулю во втором вызове.
При первом вызове GetControllerInstance тип устанавливается на HomeController, который является правильным. Код запускается в HomeController и возвращает View(). При возврате View() событие Page_Load вызывается в файле aspx. После этого он достигает строки:
httpHandler.ProcessRequest(HttpContext.Current);
То, что GetControllerInstance вызывается во второй раз.
Здесь мои биты Global.asax, которые могут иметь значение:
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
Bootstrapper.ConfigureStructureMap();
ControllerBuilder.Current.SetControllerFactory(new StructureMapControllerFactory());
}
Я очень заинтересован в том, чтобы работать над инъекциями зависимости, и был бы очень благодарен, если кто-нибудь сможет мне помочь.:)
Ответы
Ответ 1
UPDATE
Причина, по которой это происходит, заключается в том, что когда изображение указано в файле css, и это изображение отсутствует, структура маршрутизации пытается сопоставить url с контроллером. Игнорирование маршрутов, перечисленных ниже, предотвратит появление ошибки, но я решил не реализовывать ее, потому что это хороший способ получить уведомление о том, что у вас отсутствует ресурс.
Вы можете увидеть подробное объяснение вместе с примерами установки инъекции зависимостей, используя Структурную карту здесь.
У меня была такая же проблема, и я думаю, что понял. По какой-либо причине, когда вы пытаетесь предоставить свой собственный контроллер Factory, вам нужно добавить несколько дополнительных определений IgnoreRoute. Первое, что я хотел бы сделать, это добавить эту строку в метод GetControllerInstance:
if(controllerType == null)
return base.GetControllerInstance(controllerType)
Это, по крайней мере, даст вам больше информации в сообщении об ошибке относительно того, что это за запрос, вызывающий тип controllerType равным нулю. В моем конкретном случае у меня было фоновое изображение в моем файле css, например:
background: url(img/logo.gif);
Итак, что происходит, маршрутизация ищет контроллер под названием "img" и действие, которое принимает logo.gif или что-то в этом роде. Это явно не правильное поведение.
После некоторого копания я понял, что мне нужно добавить определение IgnoreRoute в мой файл Global.asax, который будет игнорировать что-либо в каталоге содержимого моего сайта следующим образом:
routes.IgnoreRoute("{Content}/{*pathInfo}");
Я все еще не уверен, почему вам не нужно делать это с помощью стандартного ControllerFactory, но тем не менее он работает.
Вероятно, вы столкнетесь с той же проблемой с favicon.ico. В частности, если вы используете google crhome. Вы также должны добавить это:
routes.IgnoreRoute("{*favicon}", new {[email protected]"(.*/)?favicon.ico(/.*)?"})
Ответ 2
Я предполагаю, что вы запрашиваете статический файл, такой как файл javascript, который не был добавлен в ваш проект или, возможно, ссылка на него имеет опечатку. Вы должны следить за веб-запросами браузеров и искать веб-запросы, которые неправильно разрешают статический файл, когда они должны. Вы можете использовать firebug в FF или fiddler, если вы используете IE для этого.