7

Estoy tratando de usar ASP.NET MVC 3 y Ninject 2.2 para inyectar un objeto de registro en un ActionFilterAttribute personalizado.MVC 3 Dependency Injection with Ninject 2.2 + Filtro de acción global

Puedo hacer que esto funcione si marcó cada controlador con el atributo personalizado.

Sin embargo, no puedo hacer que esto funcione si elimino la decoración del atributo de los controladores y trato de usar un filtro de acción global.

Aquí está el código:

bajo App_Start - NinjectMVC3.cs

using NinjectTest.Abstract; 
using NinjectTest.Concrete; 

[assembly:  WebActivator.PreApplicationStartMethod(typeof(NinjectTest.App_Start.NinjectMVC3), "Start")] 
[assembly: WebActivator.ApplicationShutdownMethodAttribute(typeof(NinjectTest.App_Start.NinjectMVC3), "Stop")] 

namespace NinjectTest.App_Start 
{ 
using Microsoft.Web.Infrastructure.DynamicModuleHelper; 

using Ninject; 
using Ninject.Web.Mvc; 

public static class NinjectMVC3 
{ 
    private static readonly Bootstrapper bootstrapper = new Bootstrapper(); 

    /// <summary> 
    /// Starts the application 
    /// </summary> 
    public static void Start() 
    { 
     DynamicModuleUtility.RegisterModule(typeof(OnePerRequestModule)); 
     bootstrapper.Initialize(CreateKernel); 
    } 

    /// <summary> 
    /// Stops the application. 
    /// </summary> 
    public static void Stop() 
    { 
     bootstrapper.ShutDown(); 
    } 

    /// <summary> 
    /// Creates the kernel that will manage your application. 
    /// </summary> 
    /// <returns>The created kernel.</returns> 
    private static IKernel CreateKernel() 
    { 
     var kernel = new StandardKernel(); 
     RegisterServices(kernel); 
     return kernel; 
    } 

    /// <summary> 
    /// Load your modules or register your services here! 
    /// </summary> 
    /// <param name="kernel">The kernel.</param> 
    private static void RegisterServices(IKernel kernel) 
    { 
     kernel.Bind<ILogger>().To<Log4NetLogger>(); 
    }  
} 

}

Global.asax.cs

using System.Web.Routing; 
using NinjectTest.Attributes; 

namespace NinjectTest 
{ 
public class MvcApplication : HttpApplication 
{ 
    public static void RegisterGlobalFilters(GlobalFilterCollection filters) 
    { 
     filters.Add(new TestLoggingAttribute()); 
     filters.Add(new HandleErrorAttribute()); 
    } 

    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 = UrlParameter.Optional } // Parameter defaults 
     ); 

    } 

    protected void Application_Start() 
    { 
     log4net.Config.XmlConfigurator.Configure(); 

     AreaRegistration.RegisterAllAreas(); 

     RegisterGlobalFilters(GlobalFilters.Filters); 
     RegisterRoutes(RouteTable.Routes); 
    } 
} 

}

TestLoggingAttribute.cs

using System.Web.Mvc; 
using Ninject; 
using NinjectTest.Abstract; 

namespace NinjectTest.Attributes 
{ 
public class TestLoggingAttribute : ActionFilterAttribute 
{ 
    [Inject] 
    public ILogger _logger { get; set; } 

    public override void OnActionExecuted(ActionExecutedContext filterContext) 
    { 

     var controller = filterContext.RouteData.Values["controller"]; 
     var action = filterContext.RouteData.Values["action"]; 

     _logger.Info("controller: " + controller + " action: " + action); 

     base.OnActionExecuted(filterContext); 
    }  

    } 
} 

HomeController.cs

using System.Web.Mvc; 
using NinjectTest.Attributes; 

namespace NinjectTest.Controllers 
{ 
//[TestLogging] 
public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     ViewBag.Message = "Welcome to ASP.NET MVC!"; 

     return View(); 
    } 

    public ActionResult About() 
    { 
     return View(); 
    } 

} 
} 

Como he mencionado si Descomentar el atributo [TestLogging] en el controlador funciona todo esto. Sin embargo, quiero usar un filtro global en su lugar. ¿Alguien me puede ayudar?

Respuesta

22

Puede que le resulte útil la following blog post. Así que en su método RegisterServices simplemente:

private static void RegisterServices(IKernel kernel) 
{ 
    kernel.Bind<ILogger>().To<Log4NetLogger>(); 
    kernel.BindFilter<TestLoggingAttribute>(FilterScope.Global, 0); 
}  

y para llevar el método BindFilter de extensión en el alcance no se olvide de añadir un adecuado using Directiva:

using Ninject.Web.Mvc.FilterBindingSyntax; 
Cuestiones relacionadas