Injecting Services into Filters

407 views Asked by At

i followed the tutorial on the Ninject-Wiki It is driving me insane, the service inside the filter is null and won't change to an object instance. I tried property Injection and decorated the interface with the [Inject]-attribute - no results. I tried injection via constructor injection (as seen below) - the filter isn't even hit! I want to use this pattern :-(

Please for the love of god (and my sanity) help me resolve this problem!

Best regards

I have got a "BaseController", that serves as a central Baseclass for all my controllers. It is decorated with the "MyExceptionLog"-Attribute.

[MyExceptionLog]
public class BaseController : Controller
{
   //omitted for brevity
}

The "MyExceptionLog" is just a empty class to mark controllers. It inherits from FilterAttribute. The filter i want to have my service injected looks as follows:

public class MyExceptionLogFilter:ActionFilterAttribute
{
    private readonly ILogger Logger;
    public MyExceptionLogFilter(ILogger logger)
    {
        Logger = logger;
    }

    public override void  OnActionExecuted(ActionExecutedContext filterContext)
    {
        if (filterContext.Exception != null)
        {
            Logger.Log(nameof(filterContext.Controller), filterContext.Exception, null);
            if (filterContext.Exception.InnerException != null)
            {
                Logger.Log(nameof(filterContext.Controller), filterContext.Exception.InnerException, null);
            }
        }
    }
}

I use a customControllerFactory to inject services into my controllers:

public class NinjectControllerFactory : DefaultControllerFactory
{
    public IKernel kernel;

    public NinjectControllerFactory()
    {
        kernel = new StandardKernel();
        AddBindings(); 
    }

    private void AddBindings()
    {
        kernel.Bind<IDbRepository>().To<DbRepository>();
        kernel.Bind<ILogger>().To<EntLibLogger>();
        kernel.BindFilter<MyExceptionLogFilter>(FilterScope.Action, 0).WhenControllerHas<MyExceptionLogAttribute>();
    }

    protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
    {
        return controllerType == null
            ? null
            : (IController)kernel.Get(controllerType);
    }
}

And finally i register the controllerFactory in my Global.Asax.cs

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);

    ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());
}
1

There are 1 answers

0
PercivalMcGullicuddy On

I ran into similar issues. I was able to get around it by injecting the service into my base api controller class.

Example:

public class BaseApiController : ApiController
{
     private readonly ILogger _logger;

     public BaseApiController(ILogger logger)
     {
        _logger = logger;
     }

     protected override void Initialize(HttpControllerContext controllerContext)
      {
         _logger.log("somes stuff");
         base.Initialize(controllerContext);
      }

}