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();