0

kinda new to MVC, and kinda new with Ninject. Playing around...

I've defined ninject in my MVC application as follows:

private static void RegisterServices(IKernel kernel)
{
    kernel.Bind(
    x => x.FromThisAssembly()
        .SelectAllClasses()
        .BindAllInterfaces()
        );
}

I have controller with a form and this ActionResult:

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

and it's returning an error: "Cannot create an instance of an interface."

Now I understand that it might not like the interface but isn't Ninject supposed to inject the real class in there? do I need to put in the actual class? if so, doesn't that take the point out of using interfaces and building a lossly-cuppuled apps?

BTW in my Index.cshtml file I have the following as the first line:

@model IMember

Thanks

developer82
  • 13,237
  • 21
  • 88
  • 153

2 Answers2

1

You seem to be confusing constructor dependency injection with action method parameters, they are not the same thing.

  • In your case you seem to want Ninject to somehow inject a concrete IMember implementation whenever a client (browser, etc) calls the Index action.

  • Bear in mind that any parameters that are going to be passed into an Action method are going to be coming from the client and not from the framework, so it wouldn't make sense to do this.

  • I am sure there is a hack you could do to make it work for e.g decorate the parameter with [Inject] or something but you've already lost at that point because you have just "revealed your sources" to the controller which is against the point of Inverting control - you might as well just pass the Ninject IKernel to the controller.

  • Anyway in your case, Ninject will only inject into the Controller constructor (assuming you have correctly wired it up) and in that respect, Doug's answer here is actually correct - if that IMember is some kind of controller dependency, then you must inject it into the constructor, and store it in for e.g. a private member so that you can later refer to it from within action methods.

  • If the IMember is not a controller dependency but is instead just a model-bound parameter that you want passed to your controller, then Dependency Injection is not the answer - the parameter should be coming from the caller.

Also, there might be another problem even if you do end up using constructor injection. The convention-based binding you are using requires that there is a single class called Member that implements IMember, i.e that the class name differs from the interface name only by lack of the initial "I". If this isn't the case for your class, then the convention-based binding will not work anyway and you need to use something explicit like

kernel.Bind<IMember>.To<MyMemberImplementationClassName>();

Hope that helps.

Community
  • 1
  • 1
Stephen Byrne
  • 7,400
  • 1
  • 31
  • 51
0

Is your RegisterServices method in the NinjectWebCommon.cs file located in the App_Start folder?

You'll also need to pass the Member object into the view kind of like below:

public class HomeController : Controller
{
    private IMember _member;

    public HomeController(IMember member)
    {
        _member = member;
    }
    public ActionResult Index()
    {
        return View(_member);
    }
}