Как я могу заставить этот старый код Ninject 2 работать с Ninject 3 и расширением MVC 2 (NinjectControllerFactory)?

В моем проекте MVC 2 я изначально использовал Ninject 2 и написал эту версию NinjectControllerFactory:

public class NinjectControllerFactory : DefaultControllerFactory
{
    private IKernel kernel = new StandardKernel(new HandiGamerServices());

    protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
    {
        try
        {
            if (controllerType == null)
            {
                return base.GetControllerInstance(requestContext, controllerType);
                // return null;
            }
        }
        catch (HttpException ex)
        {
            if (ex.GetHttpCode() == 404)
            {
                IController errorController = kernel.Get<ErrorController>();
                ((ErrorController)errorController).InvokeHttp404(requestContext.HttpContext);

                return errorController;
            }
            else
            {
                throw ex;
            }
        }

        return (IController)kernel.Get(controllerType);
    }

Наиболее важным является получение моего ErrorController, который позволяет мне корректно обрабатывать множество ошибок HTTP.

Проблема в том, что я обновился до расширения MVC 2 через Nuget, поэтому NinjectControllerFactory уже предоставлен. Можно ли использовать мое собственное переопределение GetControllerInstance? Если да, то как?


person Major Productions    schedule 10.05.2012    source источник


Ответы (1)


Я делаю именно это, и по той же причине. В Global.asax.cs я добавляю это к моему OnApplicationStarted переопределению (объявленному как виртуальный в NinjectHttpApplication):

ControllerBuilder.Current.SetControllerFactory(
    new MyControllerFactory(ControllerBuilder.Current.GetControllerFactory()));

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

Затем определите фабрику контроллеров следующим образом:

public class MyControllerFactory : IControllerFactory
{
    private IControllerFactory defaultFactory;

    public MyControllerFactory(IControllerFactory defaultFactory)
    {
        this.defaultFactory = defaultFactory;
    }

    public IController CreateController(RequestContext requestContext, string controllerName)
    {
        try
        {
            var controller = defaultFactory.CreateController(requestContext, controllerName);
            return controller;
        }
        catch (HttpException e)
        {
            // Pasted in your exception handling code here:
            if (ex.GetHttpCode() == 404)
            {
                IController errorController = kernel.Get<ErrorController>();
                ((ErrorController)errorController).InvokeHttp404(requestContext.HttpContext);

                return errorController;
            }
            else
            {
                throw ex;
            }
        }
    }

    public SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, string controllerName)
    {
        return defaultFactory.GetControllerSessionBehavior(requestContext, controllerName);
    }

    public void ReleaseController(IController controller)
    {
        defaultFactory.ReleaseController(controller);
    }
}

Как видите, для большинства целей мы просто используем фабрику контроллеров по умолчанию (Ninject), если она не может найти страницу. Для получения контроллера ошибок вы можете либо передать kernel, как вы уже делали, либо просто вызвать defaultFactory.CreateController, используя имя контроллера ошибок.

person Kirk Woll    schedule 10.05.2012
comment
Я не могу заставить фабрику «видеть» ядро, несмотря на использование оператора Ninject. Кроме того, я получаю сообщение об ошибке компиляции, в котором указано, что IController не имеет GetControllerSessionBehavior. Разница между MVC 2 и MVC 3? - person Major Productions; 12.05.2012
comment
Да, похоже, что GetControllerSessionBehavior - это только MVC3, поэтому просто не реализуйте его. Не понимаю, что вы имеете в виду, когда не видите ядро. Не могли бы вы уточнить - вы получаете ошибку компилятора? Что за сообщение об ошибке? - person Kirk Woll; 12.05.2012
comment
Ах, прости. Да, это была ошибка компилятора. Теперь я получаю ActivationException. Кажется, это происходит всякий раз, когда я пытаюсь использовать NinjectHttpApplication в моем Global.aspx.cs. Я установил Ninject MVC 2 через Nuget, и он работает, только если я оставлю MvcApplication, полученный из System.Web.HttpApplication. Я также вынужден использовать RegsiterServices NinjectWebCommon для своих привязок. - person Major Productions; 12.05.2012
comment
Выяснили, почему произошло ActivationException. Нужно внимательнее читать вики. - person Major Productions; 12.05.2012
comment
Приносим извинения за задержку с ответом, но вроде работает отлично. Спасибо! - person Major Productions; 17.05.2012