2011-08-13 16 views
16

Używam programu Ninject i rozszerzenia MVC3 instalowanego z nuget. Mój kod instalacyjny jądra znajduje się w pliku App_Start/NinjectMVC3.cs. Wszystko działa świetnie w kontrolerach, ale nie mogę się dowiedzieć, jak (właściwie) powiązać interfejsy w kodzie Global.asax.cs MvcApplication.Uzyskiwanie dostępu do jądra ninject w Application_Start

Skończyło się na użyciu hacka (tworzenie publicznej metody NinjectMVC3.GetKernel(), która zwraca bootstrap.kernel). Będzie to jednak przestarzałe i musi istnieć odpowiedni sposób na robienie tego, czego nie widzę.

Oto mój kod:

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

Istnieją dwa interfejsy Jestem zainteresowana Pierwszym z nich jest po prostu wiązania obiektu do zmiennej globalnej (The ILogger dla BackgroundWork)..

A druga dotyczy ActionFiltra. Czytam http://www.planetgeek.ch/2010/11/13/official-ninject-mvc-extension-gets-support-for-mvc3/, ale nie widzę, w jaki sposób podłącza się do rzeczywistej rejestracji (filter.Add).

Nie chcę używać funkcji Inject Inject, jeśli mogę tego uniknąć.

Jakieś przemyślenia na temat właściwego sposobu, aby to zrobić? Dzięki

Odpowiedz

23

MVC 3 wprowadza DependencyResolver, który jest zapełniany w singleton i obsługuje rozszerzenie Ninject. Można użyć, że w swojej klasie MvcApplication jeśli jest to potrzebne:

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

Teraz muszę podkreślić, że nie jest konieczne, aby to zrobić z filtrami działania. W Ninject.MVC3 ci mają użyć składni BindFilter, tak:

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

Zauważ, że musisz użyć this ponieważ BindFilter jest metoda rozszerzenie, a trzeba też odwoływać się do nazw Ninject.Web.Mvc.FilterBindingSyntax.

+1

Jeśli chodzi o BindFilter, zakładam, że używamy tego INSTEAD z filters.add? Czy mogę usunąć kod z RegisterGlobalFilters? Jednak teraz będą dwa miejsca do sprawdzenia, który filtr jest używany? Może czegoś mi brakuje. Czy powinienem zachować rejestrację filtra i mieć domyślny konstruktor? – teleball

+1

Jeśli chodzi o DependencyResolver, czy nie jest to AntiPattern (http://stackoverflow.com/questions/5653783/is-idependencyresolver-an-anti-pattern) i powód usunięcia bieżącego hackera? – teleball

+0

@user: 'RegisterGlobalFilters' jest dla filtrów, które są wykonywane przy każdej akcji w każdym kontrolerze. Składnia 'BindFilter' rejestruje filtr, który zostanie użyty, gdy określony kontroler lub akcja znajdzie określony atrybut' Attribute'; w tym przykładzie spowoduje, że 'MyFilter' zostanie uruchomiony po znalezieniu' MyFilterAttribute'. – Aaronaught

Powiązane problemy