Stuck Working Through Steven Sanderson's "ASP.NET MVC 2..."
I received a brief introduction to ASP.NET MVC in school and I am trying to expand that knowledge base with Steven Sanderson's book Pro ASP.NET MVC 2 Framework. It's been a great help, but I have hit a wall in the example that implements Ninject. I believe the DI is setup correctly, but when I try to specify the bindings for a dependency in my Ninject controller class, I receive one of two brown screens of death:
No parameterless constructor defined for this object.
Stack Trace:
[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
Object reference not set to an instance of an object.
Stack Trace:
[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.Kerne开发者_运维百科lBase..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
Here is my code in the Ninject controller class:
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
);
}
}
}
The book is pushing up against the limits of my understanding, but I am following along and have been able to debug everything up to this point. This has me stumped. Any idea where I would begin to debug this?
Both issues are related to Ninject not being setup or integrated correctly. The trunk version of Ninject allows you to bypass having to define custom controller factories. It's a cleaner setup and less confusing.
See:
- http://codeclimber.net.nz/archive/2009/08/14/how-to-use-ninject-2-with-asp.net-mvc.aspx
Additionally you should check out the article listed here
- Ninject and Custom Controller Factory
Did you update your application_start in global.asax to point to the ninject controller factory?
as such:
protected void Application_Start() {
..........
ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory ());
}
精彩评论