7

I am using Ninject MVC3(version 3.0.0.0) for my ASP.Net MVC3 application installed using NuGet Package for Dependency Injection.

Here is the Global.asax change:

public class MvcApplication : NinjectHttpApplication
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleErrorAttribute());
    }

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
        routes.IgnoreRoute("favicon.ico");
        routes.IgnoreRoute("{*favicon}", new { favicon = @"(.*/)?favicon.ico(/.*)?" });

        routes.MapRoute(
            "Default",                                              // Route name
            "{controller}/{action}/{id}",                           // URL with parameters
            new { controller = "Home", action = "Index", id = UrlParameter.Optional }  // Parameter defaults
        );
    }


    protected override IKernel CreateKernel()
    {
        var kernel = new StandardKernel();
        kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
        kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
        RegisterServices(kernel);
        return kernel;
    }

    protected override void OnApplicationStarted()
    {
        base.OnApplicationStarted();

        AreaRegistration.RegisterAllAreas();
        RegisterGlobalFilters(GlobalFilters.Filters);
        RegisterRoutes(RouteTable.Routes);
    }

    /// <summary>
    /// Load your modules or register your services here!
    /// </summary>
    /// <param name="kernel">The kernel.</param>
    private static void RegisterServices(IKernel kernel)
    {
        kernel.Bind<IUserRepository>().To<UserRepository>();
        kernel.Bind<IUserService>().To<UserService>();
        kernel.Bind<ICommonRepository>().To<CommonRepository>();
        kernel.Bind<ICommonService>().To<CommonService>();
    }
}

But it gives the following Error though i have the parameterless Constructor for my HomeController:

    System.NullReferenceException: Object reference not set to an instance of an object.

Generated: Wed, 28 Mar 2012 05:49:01 GMT

System.InvalidOperationException: An error occurred when trying to create a controller of type 'MVC3.Web.Controllers.HomeController'. Make sure that the controller has a parameterless public constructor. ---> System.NullReferenceException: Object reference not set to an instance of an object.
   at Ninject.Planning.Bindings.BindingConfiguration.GetProvider(IContext context) in c:\Projects\Ninject\ninject\src\Ninject\Planning\Bindings\BindingConfiguration.cs:line 107
   at Ninject.Planning.Bindings.Binding.GetProvider(IContext context) in c:\Projects\Ninject\ninject\src\Ninject\Planning\Bindings\Binding.cs:line 212
   at Ninject.Activation.Context.Resolve() in c:\Projects\Ninject\ninject\src\Ninject\Activation\Context.cs:line 157
   at Ninject.KernelBase.<>c__DisplayClass10.<Resolve>b__c(IBinding binding) in c:\Projects\Ninject\ninject\src\Ninject\KernelBase.cs:line 386
   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
   at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source)
   at Ninject.Planning.Targets.Target`1.GetValue(Type service, IContext parent) in c:\Projects\Ninject\ninject\src\Ninject\Planning\Targets\Target.cs:line 197
   at Ninject.Planning.Targets.Target`1.ResolveWithin(IContext parent) in c:\Projects\Ninject\ninject\src\Ninject\Planning\Targets\Target.cs:line 165
   at Ninject.Activation.Providers.StandardProvider.GetValue(IContext context, ITarget target) in c:\Projects\Ninject\ninject\src\Ninject\Activation\Providers\StandardProvider.cs:line 114
   at Ninject.Activation.Providers.StandardProvider.<>c__DisplayClass4.<Create>b__2(ITarget target) in c:\Projects\Ninject\ninject\src\Ninject\Activation\Providers\StandardProvider.cs:line 96
   at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext()
   at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
   at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
   at Ninject.Activation.Providers.StandardProvider.Create(IContext context) in c:\Projects\Ninject\ninject\src\Ninject\Activation\Providers\StandardProvider.cs:line 96
   at Ninject.Activation.Context.Resolve() in c:\Projects\Ninject\ninject\src\Ninject\Activation\Context.cs:line 157
   at Ninject.KernelBase.<>c__DisplayClass10.<Resolve>b__c(IBinding binding) in c:\Projects\Ninject\ninject\src\Ninject\KernelBase.cs:line 386
   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
   at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source)
   at Ninject.Planning.Targets.Target`1.GetValue(Type service, IContext parent) in c:\Projects\Ninject\ninject\src\Ninject\Planning\Targets\Target.cs:line 197
   at Ninject.Planning.Targets.Target`1.ResolveWithin(IContext parent) in c:\Projects\Ninject\ninject\src\Ninject\Planning\Targets\Target.cs:line 165
   at Ninject.Activation.Providers.StandardProvider.GetValue(IContext context, ITarget target) in c:\Projects\Ninject\ninject\src\Ninject\Activation\Providers\StandardProvider.cs:line 114
   at Ninject.Activation.Providers.StandardProvider.<>c__DisplayClass4.<Create>b__2(ITarget target) in c:\Projects\Ninject\ninject\src\Ninject\Activation\Providers\StandardProvider.cs:line 96
   at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext()
   at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
   at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
   at Ninject.Activation.Providers.StandardProvider.Create(IContext context) in c:\Projects\Ninject\ninject\src\Ninject\Activation\Providers\StandardProvider.cs:line 96
   at Ninject.Activation.Context.Resolve() in c:\Projects\Ninject\ninject\src\Ninject\Activation\Context.cs:line 157
   at Ninject.KernelBase.<>c__DisplayClass10.<Resolve>b__c(IBinding binding) in c:\Projects\Ninject\ninject\src\Ninject\KernelBase.cs:line 386
   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
   at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source)
   at Ninject.Planning.Targets.Target`1.GetValue(Type service, IContext parent) in c:\Projects\Ninject\ninject\src\Ninject\Planning\Targets\Target.cs:line 197
   at Ninject.Planning.Targets.Target`1.ResolveWithin(IContext parent) in c:\Projects\Ninject\ninject\src\Ninject\Planning\Targets\Target.cs:line 165
   at Ninject.Activation.Providers.StandardProvider.GetValue(IContext context, ITarget target) in c:\Projects\Ninject\ninject\src\Ninject\Activation\Providers\StandardProvider.cs:line 114
   at Ninject.Activation.Providers.StandardProvider.<>c__DisplayClass4.<Create>b__2(ITarget target) in c:\Projects\Ninject\ninject\src\Ninject\Activation\Providers\StandardProvider.cs:line 96
   at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext()
   at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
   at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
   at Ninject.Activation.Providers.StandardProvider.Create(IContext context) in c:\Projects\Ninject\ninject\src\Ninject\Activation\Providers\StandardProvider.cs:line 96
   at Ninject.Activation.Context.Resolve() in c:\Projects\Ninject\ninject\src\Ninject\Activation\Context.cs:line 157
   at Ninject.KernelBase.<>c__DisplayClass10.<Resolve>b__c(IBinding binding) in c:\Projects\Ninject\ninject\src\Ninject\KernelBase.cs:line 386
   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
   at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source)
   at Ninject.Web.Mvc.NinjectDependencyResolver.GetService(Type serviceType) in c:\Projects\Ninject\ninject.web.mvc\mvc3\src\Ninject.Web.Mvc\NinjectDependencyResolver.cs:line 56
   at System.Web.Mvc.DefaultControllerFactory.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType)
   --- End of inner exception stack trace ---
   at System.Web.Mvc.DefaultControllerFactory.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType)
   at System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType)
   at System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext, String controllerName)
   at System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory)
   at System.Web.Mvc.MvcHandler.<>c__DisplayClass6.<BeginProcessRequest>b__2()
   at System.Web.Mvc.SecurityUtil.<>c__DisplayClassb`1.<ProcessInApplicationTrust>b__a()
   at System.Web.Mvc.SecurityUtil.<GetCallInAppTrustThunk>b__0(Action f)
   at System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action)
   at System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust[TResult](Func`1 func)
   at System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state)
   at System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state)
   at System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData)
   at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

UPDATE:

Below is the Code from the HomeController:

public class HomeController : Controller
    {
        #region Declaration
        public ICommonService _commonService { get; set; }
        #endregion

        #region Constructor

        public HomeController()
        {

        }

        public HomeController(ICommonService commonService)
        {
            this._commonService = commonService;
        }
        #endregion

        public ActionResult Index()
        {
            return View();
        }

Constructor of CommonService and CommonRepository:

public class CommonService : ICommonService
    {
        #region Declaration
        private readonly ICommonRepository _repository;
        #endregion

        #region Constructor
        public CommonService(ICommonRepository repository)
        {
            this._repository = repository;
        }
        #endregion

 public class CommonRepository : ICommonRepository
    {
        #region Declaration
        private DBContainer _context = new DBContainer();
        #endregion

        #region Constructor
        public CommonRepository()
        {

        }
        #endregion

Am i missing any other Reference here?

Prasad
  • 58,881
  • 64
  • 151
  • 199
  • check if your parameterless constructor is public – Ventsyslav Raikov Mar 28 '12 at 07:24
  • Bond, Yes i have it as public. public HomeController() { } – Prasad Mar 28 '12 at 07:30
  • Can you share the controller in question (without action methods)? – tpeczek Mar 28 '12 at 07:52
  • @tpeczek, I have updated my question with the Controller. – Prasad Mar 28 '12 at 08:44
  • I don´t know how ninject works, cause i´m using unity. But Unity uses by default the ctor with the most parameters. May be Ninject behaves the same and tries to inject ICommonService in to your HomeController. Try removing all ctors and leave only the parameterless ctor. Then try again resolving your instance via Ninject – Jehof Mar 28 '12 at 08:53
  • The stacktrace makes no sense. I cannot see how a NullRefException could happen there. Please open a bug report on github and provide a sample project demonstrating this issue. – Remo Gloor Apr 09 '12 at 12:21
  • Check out this post that I answered. It should get you up and running: http://stackoverflow.com/a/11471180/1220302 – anAgent Nov 14 '12 at 18:23

3 Answers3

7

This is how constructor selection in Ninject works:

  1. If a constructor has an [Inject] attribute, it is used. If multiple constructors have an [Inject] attribute, Ninject will throw a NotSupportedException.
  2. If no constructors have an [Inject] attribute, Ninject will select the one with the most parameters that Ninject understands how to resolve.
  3. If no constructors are defined, Ninject will select the default parameterless constructor.

In your case Ninject is most probably not selecting the parameterless constructor because it believes he knows how to resolve ICommonService. Please try to decorate your parameterless constructor with [Inject] attribute if you want Ninject to use it or make further investigation why ICommonService isn't being resolved.

tpeczek
  • 23,867
  • 3
  • 74
  • 77
  • When i used the [Inject] attribute on parameterless constructor, it works fine, but the ICommonService is not getting resolved. – Prasad Mar 28 '12 at 09:39
  • So the problem is Ninject is not able to construct ICommonService. I don't see binding for it in your RegisterServices method (Global.asax). In best case Ninject is using implicit self-binding but it doesn't give anything that can be constructed. What is exact type of this service to what it should be resolved? – tpeczek Mar 28 '12 at 09:55
  • I have tried adding the ICommonService in RegisterServices of my Global.asax, but still it doesn't gets resolved and just updated my question. – Prasad Mar 28 '12 at 10:03
  • Of course after adding the ICommonService to RegisterServices you have removed the [Inject] attribute so the Ninject would use the constructor with the parameter right? – tpeczek Mar 28 '12 at 10:06
  • When i remove the [Inject] attribute from the parameterless constructor, it again throws the "Make sure that the controller has a parameterless public constructor" error – Prasad Mar 28 '12 at 10:20
  • In that case please share constructors of CommonService as well. – tpeczek Mar 28 '12 at 10:51
  • tpeczek, I have updated my question with constructors of CommonService and CommonRepository. – Prasad Mar 28 '12 at 11:02
  • From static analysis the only suspicious line is private DBContainer _context = new DBContainer(); can you change it to this private DBContainer _context = null; just to see if the controller will get constructed (I'm aware that this will most probably cause some other exception a moment later). – tpeczek Mar 28 '12 at 11:14
  • I have tried assigning null to _context, but still the ICommonService doesn't resolves. – Prasad Mar 28 '12 at 13:14
  • So when you set null it doeasn't resolve ICommonService and doesn't throw an exception? You must remember that Ninject will try to resolve ICommonService only when using the constructor with parameter (when you are not using [Inject] attribute), and the "Make sure that the controller has a parameterless public constructor" error is only high level message, the actual problem is NullReferenceException which is being throwed "somewhere on the way" while creating entire object tree for your controller. – tpeczek Mar 28 '12 at 13:19
  • "DBContainer _context" is not an interface. Its the entity to access the DB information. Also it doesn't throw any exception when i use [Inject] attribute on parameterless constructor, but the interface doesn't resolves. – Prasad Mar 28 '12 at 13:23
  • It will not throw exception when you using [Inject] attribute because Ninject doesn't even try to resolve ICommonService (and it will not). The real reason behind exception when you are not using [Inject] attribute is NullReferenceException somewhere in the object graph for building CommonService. From the code you have posted the best reason is that DBContainer() is throwing this exception. This is why I asked you to change it to null and try without [Inject] attribute. – tpeczek Mar 28 '12 at 13:39
  • DBContainer() is not an Interface. Its the EF Context to access the DB. Its working when i use without Ninject DI like: this._commonService = new CommonService(); in the parameterless Constructor – Prasad Mar 28 '12 at 14:04
  • In that case nothing more can be done by static analysis. I will try to recreate your issue for some intense debuging. – tpeczek Mar 28 '12 at 14:29
2

If you recently retargeted the MVC application from .NET 4.0 to 4.5 or the other way around, then you get the exact same symptom. It is fixed by referencing the correct .NET version DLLs for the target.

If you are using the Ninject, Ninject.MVC3 and Ninject.Web.Common nugets then you will find all .NET targets there.

angularsen
  • 8,160
  • 1
  • 69
  • 83
1

Quote from https://github.com/ninject/ninject/wiki/Injection-Patterns:

The primary DI pattern is Constructor Injection. When activating an instance of a type Ninject will choose one of the type’s constructors to use by applying the following rules in order:-

If a constructor has an [Inject] attribute, it is used (but if you apply the attribute to more than one, Ninject will throw a NotSupportedException at runtime upon detection).

If no constructors have an [Inject] attribute, Ninject will select the one with the most parameters that Ninject understands how to resolve.

If no constructors are defined, Ninject will select the default parameterless constructor (assuming there is one).

  • When i remove the parameterless Constructor, it throws the "Make sure that the controller has a parameterless public constructor" error – Prasad Mar 28 '12 at 10:58