views:

52

answers:

1

I'm using the Ninject.Web.Mvc (the MVC 2 version) add-on with ASP.NET MVC 2. This is an excerpt of my Global.asax.cs:

protected override void OnApplicationStarted()
{
    AreaRegistration.RegisterAllAreas();
    RegisterRoutes(RouteTable.Routes;
    // RegisterAllControllersIn() is not available in the MVC 2 version of Ninject
}

protected override IKernel CreateKernel()
{
    var kernel = new StandardKernel();
    kernel.Bind<IRepository>().To<NHibernateRepository>();

    return kernel;
}

I also have a base RepositoryController:

public class RepositoryController : Controller
{
    protected IRepository Repository { get; set; }

    public RepositoryController()
    {

    }

    public RepositoryController(IRepository repository)
    {
        Repository = repository;
    }
}

So as you can see, it's a very simple setup where RepositoryController expects to be injected with an instance of an IRepository, and Ninject is configured to use a concrete instance of NHibernateRepository. However, this doesn't work and the Repository property is null whenever I try to access it in a controller. However, if I change the code to this instead:

[Inject]
public IRepository Repository { get; set; }

Then it works fine. Does anyone know why constructor injection isn't working, but property injection is?

+1  A: 

Try removing the parameterless constructor.

Ninject might be picking the wrong constructor to resolve.

To test it out, you could put a breakpoint in both constructors and see which one fires, but I have a feeling it's the parameterless one.

Joseph
Whoa you're right! That's really strange because according to the documentation, it will select either the one that has the `[Inject]` attribute (which I tried, but it still picks the parameterless one), or the constructor that has the most parameters that Ninject knows how to process. http://github.com/ninject/ninject/wiki/Injection-Patterns
Daniel T.
@Daniel that's correct, and if you were using straight up Ninject I would bet it would actually work that way, but I have a feeling that the MVC extension doesn't quite do that. If you had the kernel yourself and did Kernel.Resolve<RepositoryController>() then you would probably get what you were expecting (but then again you didn't register the controller in your bindings, the mvc extension does that automagically which might be the problem)
Joseph
I've found the source of the problem. My `RepositoryController` is a base class for all my other controllers that need to use my repository. The sub-classes don't have constructors, which caused Ninject to match its third condition: "If no constructors are defined, Ninject will select the default parameterless constructor." So in other words, it was looking in the sub-class, not finding any constructors, and used the default parameterless constructor, which happens to be the one I defined in the base class.
Daniel T.