1

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());
}
ChrisBint
  • 12,773
  • 6
  • 40
  • 62
BenAlp
  • 11
  • 1
  • 1
    Don't put your logic in attributes; put it in proper objects that use attribute data as input: http://stackoverflow.com/a/7194467/126014 – Mark Seemann Jun 23 '15 at 13:58
  • 1
    [Don't inject dependencies into attributes](https://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=98). – Steven Jun 23 '15 at 14:17
  • So what you both propose is rather than using an attribute but using an IActionFilter (in my case the IExceptionFilter), hook it up on Application_Start and be happy? – BenAlp Jun 23 '15 at 15:06

1 Answers1

1

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

}
PercivalMcGullicuddy
  • 5,263
  • 9
  • 46
  • 65