I am trying to use ASP.NET MVC 3 and Ninject 2.2 to inject a logger object into a custom ActionFilterAttribute.
I am able to get this to work if I mark each controller with the custom attribute.
However I cannot get this to work if I remove the attribute decoration from the controllers and try to use a global action filter.
Here is the code:
under 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();
}
}
}
Like I mentioned if I uncomment the [TestLogging] attribute in the controller this all works. However I want to use a global filter instead. Can someone help me out?