Подтвердить что ты не робот

Пользовательский контроллер 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());
    }

Я очень заинтересован в том, чтобы работать над инъекциями зависимости, и был бы очень благодарен, если кто-нибудь сможет мне помочь.:)

4b9b3361

Ответ 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 для этого.