2011-08-13 8 views
16

Estoy usando Ninject y la extensión MVC3 instalada con nuget. Mi código de configuración del núcleo está en el archivo App_Start/NinjectMVC3.cs. Todo funciona muy bien en los controladores, pero no puedo encontrar la forma de vincular (correctamente) las interfaces en el código Global.asax.cs MvcApplication.Acceso al kernel ninject en Application_Start

Terminé usando un truco (creando un método público NinjectMVC3.GetKernel() que devuelve bootstrap.kernel). Sin embargo, eso será obsoleto, y debe haber una manera adecuada de hacer esto que no estoy viendo.

Aquí está mi código:

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

Hay dos interfaces Me interesa La primera es simplemente la unión de un objeto a una variable global (la ILogger para la BackgroundWork)..

Y el segundo es para un ActionFilter. Leí http://www.planetgeek.ch/2010/11/13/official-ninject-mvc-extension-gets-support-for-mvc3/, pero no veo cómo se conecta al registro real (filter.Add).

No quiero utilizar Property Inject si puedo evitarlo.

¿Alguna idea sobre la forma correcta de hacerlo? Gracias

Respuesta

23

MVC 3 introduce el DependencyResolver que se completa en un singleton, y la extensión Ninject lo admite. Se podría usar eso en su clase MvcApplication si lo necesita:

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

Ahora debo señalar que no es necesario hacer esto con filtros de acción. En Ninject.MVC3 que se supone que utilizar la sintaxis BindFilter, así:

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

Tenga en cuenta que usted tiene que utilizar this porque BindFilter es un método de extensión, y también hay que hacer referencia al espacio de nombres Ninject.Web.Mvc.FilterBindingSyntax.

+1

Con respecto al BindFilter, ¿estoy asumiendo que usemos eso EN LUGAR de filters.add? Entonces, ¿puedo eliminar el código en RegisterGlobalFilters? Sin embargo, ahora habría dos lugares para verificar para ver qué filtro se está utilizando. Tal vez me estoy perdiendo algo. ¿Debo mantener el registro del filtro y tener un constructor predeterminado? – teleball

+1

En cuanto a DependencyResolver, ¿no es un AntiPattern (http://stackoverflow.com/questions/5653783/is-idependencyresolver-an-anti-pattern) y la razón por la que se está eliminando el hack actual? – teleball

+0

@user: 'RegisterGlobalFilters' es para filtros que se ejecutan en cada acción en cada controlador. La sintaxis 'BindFilter' registra un filtro que se utilizará cuando se encuentre un' Atributo' específico en un controlador o acción; en este ejemplo, hará que 'MyFilter' se ejecute siempre que se encuentre' MyFilterAttribute'. – Aaronaught

Cuestiones relacionadas