7

我想使用ASP.NET MVC 3和Ninject 2.2注入记录器对象到自定义ActionFilterAttribute。MVC 3依赖注入与Ninject 2.2 +全局动作筛选器

我能够得到这个工作,如果我标记每个控制器的自定义属性。

但是我不能得到这个工作,如果我从控制器中删除属性装饰,并尝试使用全局操作过滤器。

下面是代码:

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

} 
} 

就像我提到的,如果我在这个控制器的所有作品取消注释[TestLogging]属性。不过,我想要使用全局过滤器。 有人可以帮我吗?

回答

22

您可能会发现following blog post有用。因此,在您RegisterServices方法简单:

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

,并带来了BindFilter扩展方法为范围不要忘记添加适当using指令:

using Ninject.Web.Mvc.FilterBindingSyntax;