2

Ninject를 처음 설치하려고합니다. IRepository 인터페이스와 저장소 구현이 있습니다. 내가 ASP.NET MVC를 사용하고, 나는 그렇게 같은 구현을 주입하기 위해 노력하고있어 : 여기 BaseModule 클래스의Ninject가 발사되지 않습니까?

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

을 그리고 :

여기

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 BaseModule : StandardModule 
    { 
     public override void Load() 
     { 
      Bind<IRepository<BlogPost>>().To<Repository<BlogPost>>(); 
     } 
    } 

_repo.Insert (b)를 사용하려고 할 때 Index() 동작을 탐색 할 때 "개체 참조가 개체의 인스턴스로 설정되지 않았습니다."라는 메시지가 나타납니다. 나는 무엇을 떠나야 하는가?

+1

사용하는 Ninject에 어떤 버전 (예제로 사용 HomeController)과 같은 코드를 모든 컨트롤러를 찾는 생성과 AutoControllerModule

생각해? –

+0

버전 1.0을 사용 중입니다. –

답변

3

Ninject 1.0에는 기본적으로 MVC가 지원되지 않았습니다. 웹상에 Ninject 1.0이 흩어져있는 상태에서 MVC를 사용하는 다양한 방법이 있습니다.

MVC 지원을 포함하는 Ninject 트렁크에서 최신 코드를 가져 오는 것이 좋습니다. 그런 다음 응용 프로그램의 시작 지점으로 다음을 사용

원래 구현에 비해 강조 할 몇 가지가 있습니다

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를 사용하고 컨트롤러를 등록해야하는 이유는 무엇입니까? 나는 그들을 (아직) 주입 시키려고하지 않고있다. –

+2

널 참조 예외는 _repo가 ​​컨트롤러에 주입되지 않기 때문에 null이됩니다. Ninject가 저장소에 저장소를 삽입하려면 Ninject가 컨트롤러를 만들어야합니다. Ninject가 컨트롤러를 만들려면 컨트롤러에 대해 등록 된 컨트롤러가 필요합니다. 마지막으로 MVB에 연결하여 Ninject를 사용하여 ControllerBuilder가 처리하는 컨트롤러를 작성해야합니다. –

2

당신은 커널을 만들 때 사용자가 지정한 모듈의 목록에 AutoControllerModule를 추가 할 필요가, 아래에 보여

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

AutoControllerModule이 Ninject에 1의 MVC 지원의 일부입니다. 엑스. MVC 컨트롤러 클래스의 생성자에 제공 한 어셈블리를 스캔하고 자동 바인딩합니다. 코드에서 저장소를 제대로 바인딩했지만 Ninject는 컨트롤러를 활성화하지 않습니다. 당신의 저장소가 당신의 HomeController 클래스의 인스턴스에 주입되기 위해서, Ninject는 컨트롤러 생성과 활성화를 담당 할 필요가 있습니다. AutoControllerModule이 없으면 MVC는 컨트롤러 생성을 담당합니다. 그러므로, Ninject는 어떤 멤버도 투입 할 기회를 결코 얻지 못합니다. Ninject가 컨트롤러를 생성하고 활성화하는 작업을 담당하면 예상대로 주입이 수행됩니다.

Bind<HomeController>.ToSelf(); 
+0

도움을 주셔서 감사합니다. 그러나 요한이 먼저 대답했습니다. 나는 당신에게 두 신용을 줄 수 있었으면 좋겠다 :) –

+0

당신을 환영합니다! –