2011-08-13 2 views
16

Ninject와 Nuget와 함께 설치된 MVC3 확장을 사용하고 있습니다. 내 커널 설정 코드는 App_Start/NinjectMVC3.cs 파일에 있습니다. 모든 것이 컨트롤러에서 훌륭하게 작동하지만 Global.asax.cs MvcApplication 코드에서 인터페이스를 (제대로) 바인딩하는 방법을 알 수 없습니다.Application_Start에서 ninject 커널에 액세스

나는 해킹 (bootstrap.kernel을 반환하는 공용 NinjectMVC3.GetKernel() 메소드를 생성)을 사용했다. 그러나, 그것은 비추천 될 것이며, 이것을 볼 수있는 적절한 방법이 있어야합니다. 나는에 관심이 있어요 두 개의 인터페이스가 있습니다

public class LogFilterAttribute : ActionFilterAttribute 
{ 
    private IReportingService ReportingService { get; set; } 
    public LogFilterAttribute(IReportingService reportingService) 
    { 
     this.ReportingService = reportingService; 
    } 
    ... 
} 

public class MvcApplication : System.Web.HttpApplication 
{ 
    public static void RegisterGlobalFilters(GlobalFilterCollection filters) 
    { 
     filters.Add(new HandleErrorAttribute()); 
     filters.Add(new LogFilterAttribute() ); 
    } 
    ... 
    protected void Application_Start() 
    { 
     ... 
     RegisterGlobalFilters(GlobalFilters.Filters); 
     // NOTE hack: 
     var kernel = NinjectMVC3.GetKernel(); 
     var logger = kernel.Get<ILogger>(); 
     var bw = new BackgroundWork(logger); 
     Application["BackgroundWork"] = bw; 
     bw.Start(); 
    } 
} 

첫 번째는 바로 글로벌 변수합니다 (BackgroundWork에 대한 ILogger입니다)에 개체를 바인딩되어

여기 내 코드입니다..

두 번째는 ActionFilter입니다. http://www.planetgeek.ch/2010/11/13/official-ninject-mvc-extension-gets-support-for-mvc3/을 읽었지만 실제 등록 (filter.Add)에 어떻게 연결되는지는 알 수 없습니다.

나는 그것을 피할 수 있으면 Property Inject를 사용하고 싶지 않습니다.

올바른 방법에 대한 의견이 있으십니까? 감사합니다.

답변

23

MVC 3은 싱글 톤으로 채워지는 DependencyResolver을 소개하며, Ninject 확장은 그것을 지원합니다.

protected void Application_Start() 
{ 
    // ... 
    var logger = DependencyResolver.Current.GetService<ILogger>(); 
} 

을 지금이 행동 필터를 사용하여이 작업을 수행 할 필요가 있음을 지적한다 : 당신이 그것을 필요로하는 경우에 당신은 당신의 MvcApplication 수업 시간에 그것을 사용할 수 있습니다. 당신이 BindFilter이 확장 방법이기 때문에 this를 사용할 필요가

// Declare empty attribute 
public class MyFilterAttribute : FilterAttribute { } 

// Dependency module 
public class MyModule : NinjectModule 
{ 
    public override void Load() 
    { 
     // Other bindings 
     // ... 
     this.BindFilter<MyActionFilter>(FilterScope.Action, 1) 
      .WhenControllerHas<MyFilterAttribute>(); 
    } 
} 

참고, 당신은 또한 Ninject.Web.Mvc.FilterBindingSyntax 네임 스페이스를 참조 할 수 있습니다 Ninject.MVC3에서 그렇게처럼 BindFilter 구문을 사용하기로되어있다.

+1

BindFilter와 관련하여 필자는 filters.add 대신에 BindFilter를 사용한다고 가정합니다. 그래서 RegisterGlobalFilters에서 코드를 제거 할 수 있습니까? 그러나 이제는 어떤 필터가 사용되고 있는지 확인하기위한 두 곳이있을 것입니다. 어쩌면 나는 뭔가를 놓치고있다. 필터 등록을 유지하고 기본 생성자를 사용해야합니까? – teleball

+1

DependencyResolver에 대해서는 AntiPattern (http://stackoverflow.com/questions/5653783/is-idependencyresolver-an-anti-pattern)이 아니며 현재 해킹이 제거되는 이유는 무엇입니까? – teleball

+0

@user :'RegisterGlobalFilters'는 모든 컨트롤러의 모든 동작에서 실행되는 필터 용입니다. 'BindFilter' 문법은 특정'Attribute'가 컨트롤러 나 액션에서 발견 될 때 사용할 필터를 등록합니다. 이 예에서는'MyFilterAttribute'가 발견 될 때마다'MyFilter'가 실행됩니다. – Aaronaught

관련 문제