Застрял, работая через Стивена Сандерсона "ASP.NET MVC 2 ..." - PullRequest
1 голос
/ 19 июля 2011

Я получил краткое введение в ASP.NET MVC в школе и пытаюсь расширить эту базу знаний с помощью книги Стивена Сандерсона Pro ASP.NET MVC 2 Framework . Это очень помогло, но я попал в стену в примере, который реализует Ninject. Я считаю, что DI настроен правильно, но когда я пытаюсь указать привязки для зависимости в моем классе контроллера Ninject, я получаю один из двух коричневых экранов смерти:

Для этого объекта не определен конструктор без параметров.

Трассировка стека:

[MissingMethodException: No parameterless constructor defined for this object.]
   System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) +0
   System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache) +98
   System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean skipCheckThis, Boolean fillCache) +241
   System.Activator.CreateInstance(Type type, Boolean nonPublic) +69
   System.Activator.CreateInstance(Type type) +6
   System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType) +491

[InvalidOperationException: An error occurred when trying to create a controller of type 'SportsStore.WebUI.Controllers.ProductsController'. Make sure that the controller has a parameterless public constructor.]
   System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType) +628
   System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext, String controllerName) +204
   System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory) +193
   System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +160
   System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) +80
   System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +45
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +8898152
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +184

Ссылка на объект не установлена ​​для экземпляра объекта.

Трассировка стека:

[NullReferenceException: Object reference not set to an instance of an object.]
   SportsStore.WebUI.Infrastructure.SportsStoreServices.Load() in D:\Visual Studio 2010\Projects\CSharp2010AndDotNet4PlatformBook\SportsStore\SportsStore.WebUI\Infrastructure\NinjectControllerFactory.cs:33
   Ninject.Modules.NinjectModule.OnLoad(IKernel kernel) in c:\Projects\Ninject\ninject\src\Ninject\Modules\NinjectModule.cs:60
   Ninject.KernelBase.Load(IEnumerable`1 modules) in c:\Projects\Ninject\ninject\src\Ninject\KernelBase.cs:222
   Ninject.KernelBase..ctor(IComponentContainer components, INinjectSettings settings, INinjectModule[] modules) in c:\Projects\Ninject\ninject\src\Ninject\KernelBase.cs:102
   Ninject.KernelBase..ctor(INinjectModule[] modules) in c:\Projects\Ninject\ninject\src\Ninject\KernelBase.cs:57
   Ninject.StandardKernel..ctor(INinjectModule[] modules) in c:\Projects\Ninject\ninject\src\Ninject\StandardKernel.cs:31
   SportsStore.WebUI.Infrastructure.NinjectControllerFactory..ctor() in D:\Visual Studio 2010\Projects\CSharp2010AndDotNet4PlatformBook\SportsStore\SportsStore.WebUI\Infrastructure\NinjectControllerFactory.cs:18
   SportsStore.WebUI.MvcApplication.Application_Start() in D:\Visual Studio 2010\Projects\CSharp2010AndDotNet4PlatformBook\SportsStore\SportsStore.WebUI\Global.asax.cs:32

Вот мой код в классе контроллеров Ninject:

public class NinjectControllerFactory : DefaultControllerFactory
{
    // A Ninject "kernel" is the things that can supply object instances
    private IKernel kernel = new StandardKernel(new SportsStoreServices());

    // ASP.NET MVC calls this to get the controller for each request
    protected override IController GetControllerInstance(RequestContext context, Type controllerType)
    {
        if (controllerType == null)
            return null;
        return (IController)kernel.Get(controllerType);
    }

    // Configures how abstract service types are mapped to concrete implementations
    private class SportsStoreServices : NinjectModule
    {
        public override void Load()
        {
            Bind<IProductsRepository>()
                .To<SqlProductsRepository>()
                .WithConstructorArgument("connectionString",
                    ConfigurationManager.ConnectionStrings["AppDb"].ConnectionString
                    );
        }
    }
}

Книга выходит за пределы моего понимания, но я следую и могу отлаживать все до этого момента. Это поставило меня в тупик. Любая идея, где я бы начал отлаживать это?

Ответы [ 2 ]

2 голосов
/ 19 июля 2011

Обе проблемы связаны с неправильной настройкой или интеграцией Ninject. Магистральная версия Ninject позволяет вам обходиться без необходимости определять собственные фабрики контроллеров. Это более чистая настройка и менее запутанная.

См:

Кроме того, вам следует ознакомиться со статьей, перечисленной здесь

1 голос
/ 14 декабря 2011

Обновили ли вы свой application_start в global.asax, чтобы он указывал на фабрику контроллеров ninject?

как таковой:

protected void Application_Start() {
..........

  ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory ());
}
...