2

我正在尝试第一次设置Ninject。我有一个IRepository接口和一个Repository实现。我使用ASP.NET MVC和我试图注入像这样实现:Ninject未开火?

public class HomeController : Controller 
{ 
    [Inject] public IRepository<BlogPost> _repo { get; set; } 

    public ActionResult Index() 
    { 
     ViewData["Message"] = "Welcome to ASP.NET MVC!"; 

     var b = new BlogPost 
        { 
         Title = "My First Blog Post!", 
         PostedDate = DateTime.Now, 
         Content = "Some text" 
        }; 

     _repo.Insert(b); 

     return View(); 
    } 

    // ... etc 
} 

而这里的Global.asax:

public class MvcApplication : NinjectHttpApplication 
{ 
    public static void RegisterRoutes(RouteCollection routes) 
    { 
     routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 

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

    } 

    protected override void OnApplicationStarted() 
    { 
     RegisterRoutes(RouteTable.Routes); 
    } 

    protected override IKernel CreateKernel() 
    { 
     IKernel kernel = new StandardKernel(new BaseModule()); 
     return (kernel); 
    } 
} 

而这里的BaseModule类:

public class BaseModule : StandardModule 
    { 
     public override void Load() 
     { 
      Bind<IRepository<BlogPost>>().To<Repository<BlogPost>>(); 
     } 
    } 

尝试使用_repo.Insert(b)时,当我浏览到Index()动作时,我得到“对象引用未设置为对象的实例”。我要抛弃什么?

+1

什么版本Ninject您使用的是? – 2009-08-05 02:08:08

+0

我正在使用版本1.0 – 2009-08-05 13:19:44

回答

3

Ninject 1.0没有开箱即用的MVC支持。在网络上散布Ninject 1.0的方式有很多种。

我建议从Ninject树干获取最新代码,其中包括MVC支持。然后使用以下作为起点为您的应用:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Reflection; 
using System.Web; 
using System.Web.Mvc; 
using System.Web.Routing; 
using DemoApp.Models; 
using Ninject.Core; 
using Ninject.Framework.Mvc; 

namespace DemoApp 
{ 
    public class MvcApplication : NinjectHttpApplication 
    { 
     protected override void RegisterRoutes(RouteCollection routes) 
     { 
      routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 

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

     protected override IKernel CreateKernel() 
     { 
      return new StandardKernel(new BaseModule(), new AutoControllerModule(Assembly.GetExecutingAssembly())); 
     } 
    } 
} 

有几件事情来突出与你原来的实现......

  • Ninject有 实现名 NinjectHttpApplication - 一个在 Ninject.Framework.Web和一个在 Ninject.Framework.Mvc。您看起来为 正在使用前者,因为后面的 包含受保护的RegisterRoutes() 方法。
  • 您需要一种方法将Ninject挂钩到控制器创建中,这是使用ControllerBuilder完成的。 Ninject.Framework.Mvc.NinjectHttpApplication注册NinjectControllerFactory。如果使用Ninject 1.0,则必须自己提供。
  • 您需要在容器中注册控制器。您可以手动完成,但是使用最新的代码提供,并且AutoControllerModule为您自动注册控制器!
+0

为什么我需要使用ControllerBuilder和注册控制器?我没有试图注入他们(还)。 – 2009-08-05 13:20:24

2

您需要的AutoControllerModule添加到您创建的内核时指定的模块列表,下面显示:

protected override IKernel CreateKernel() 
{ 
    IKernel kernel = new StandardKernel(
         new BaseModule(), 
         new AutoControllerModule(Assembly.GetExecutingAssembly()) 
        ); 
    return (kernel); 
} 

AutoControllerModule是Ninject 1中的MVC支持的一部分。 X。它扫描你为MVC控制器类提供给它的构造函数的程序集并自动绑定它们。在代码中,您已经正确绑定了您的存储库,但Ninject不负责激活您的控制器。为了将您的存储库注入到您的类的实例中,Ninject需要负责创建和激活控制器。如果没有AutoControllerModule,MVC仍然负责创建控制器;因此,Ninject从来没有机会注入任何成员。一旦Ninject负责创建和激活控制器,注入将按预期发生。

认为AutoControllerModule如发现所有控制器和产生这样的代码(HomeController的使用为例)的:

Bind<HomeController>.ToSelf();