Ninject.MVC3, Nuget, WebActivator oh my

2019-03-09 22:08发布

问题:

I want to setup Ninject to do a simple test, as well as demonstrate the ease-of-setup using Nuget. I want to resolve a sample service.

public interface ITestService
{
    string GetMessage();
}
public class TestService : ITestService 
{
    public string GetMessage() { return "hello world"; }
}

I run the NuGet Install-Package NinjectMVC3 .... it nicely drops NinjectMVC3.cs into my App_Start folder, decorated with some WebActivator attributes to get it all loaded.

Next I add my binding in the NinjectMVC3.RegisterServices method:

private static void RegisterServices(IKernel kernel)
{
   kernel.Bind<ITestService>().To<TestServiceOne>();
}

Now I want to 'use' Ninjet to resolve my ITestService.

public ActionResult Index()
{
  //[Ninject, give me the service I need]
  ITestService service = ??? 

  ViewBag.Message = service.GetMessage();
  return View();
}

Is there another part to setting up Ninject? Do I need to provide a resolver?

What is the code I need to resolve my ITestService.

thanksasking help »

** * * * * * * * * * * * Update: * * * * * * * * * * * * * * * * **

Thanks for the great responses regarding 'controller constructor' injection. Simply adding a constructor with the ITestServcice as a param .... BAMM !!!

private ITestService _service;

public HomeController(ITestService service)
{
  _service = service
}
public ActionResult Index()
{
  ViewBag.Message = _service.GetMessage();
  return View();
}

Now what is the ideal solution for, when I need to get the Kernel directly.

var kernel = ... // Go grab the kernel from ????? (thanks Judah).
ITestService service = kernel.Get<ITestService>();

I can see the NinjectMVC3 class creates the Kernel, but does not hold or expose a reference to it, nor can I find a obvious class/method to 'get the kernel'.

I assume thee is a Ninject way to get it, but not sure.

** * * * * * * * * * * * (Final) Update: * * * * * * * * * * * * * * * * **

Thanks again for the answers and comments ....

Correction: The NinjectMVC3 class creates the Kernel, and does hold reference to the 'Bootstrapper', which as a IKernel on it.

So I added a 'resolve' method to the App_Start/NinjectMVC3 class ... works great.

public static class NinjectMVC3 /// created by the NinjectMVC3 NuGet  Packagae
{
   // add method to provide a global resolver.   
   public static T Resolve<T>()
   {
       return bootstrapper.Kernel.Get<T>();
   }
}

回答1:

Add the ITestService as a constructor parameter to your controller:

private ITestService service;

public MyController(ITestService service)
{
   this.service = service;
}

public ActionResult Index()
{
  ViewBag.Message = this.service.GetMessage();
  return View();
}

Ninject will automatically inject the ITestService into your controller. Then use the service field inside your Index method.


Alternately, if you don't want Ninject to inject into your controller constructor, you can keep around the kernel you create, then inside your Index method, you call kernel.Get<ITestService>() to grab an instance:

public ActionResult Index()
{
  var kernel = ... // Go grab the kernel we created back in app startup.
  ITestService service = kernel.Get<ITestService>();

  ViewBag.Message = service.GetMessage();
  return View();
}

Have a look at Ninject dependency inject for controllers in MVC3.



回答2:

Steps:

  1. Create a new ASP.NET MVC 3 project
  2. Install the NuGet package from the Package Console: Install-Package Ninject.MVC3
  3. In HomeController:

    public class HomeController : Controller
    {
        private readonly ITestService _service;
        public HomeController(ITestService service)
        {
            _service = service;
        }
    
        public ActionResult Index()
        {
            ViewBag.Message = _service.GetMessage();
            return View();
        }
    }
    
  4. In App_Start/NinjectMVC3.cs:

    private static void RegisterServices(IKernel kernel)
    {
        kernel.Bind<ITestService>().To<TestService>();
    }