Dependency Injection for ASP.NET WebAPI ActionFilters using Ninject not working
Asked Answered
C

3

11

I am attempting to set up DI on ActionFilters in ASP.NET WebAPI using Ninject. I followed the instructions here: https://github.com/ninject/Ninject.Web.WebApi/wiki/Dependency-injection-for-filters

I create my ActionFilter like so:

public class ApiAuthorizeFilter : AbstractActionFilter
{
    private readonly IValidateApiTokenService _validateApiTokenService;

    public ApiAuthorizeFilter(IValidateApiTokenService validateApiTokenService)
    {
        _validateApiTokenService = validateApiTokenService;
    }

    public override bool AllowMultiple => true;

    public override void OnActionExecuting(HttpActionContext actionContext)
    {
    }

    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {
    }
}

I configured like so:

kernel.BindHttpFilter<ApiAuthorizeFilter>(FilterScope.Controller);

My understanding based on the info at the above link is that the ActionFilter should then run for all Actions in all WebAPI controllers. However, I've set breakpoints at both overridden methods in the filter and it never gets hit. I have set a breakpoint at the configuration and can confirm that it is being executed.

What am I missing? I need this ActionFilter to run on all Actions in every ApiController in my project.

Corrugation answered 15/5, 2016 at 16:11 Comment(3)
How are you configuring injection of the constructor parameter for ApiAuthorizeFilter?Coraleecoralie
@Coraleecoralie that's what I'm trying to solve. I want IValidateApiTokenService to be injected into my filter.Corrugation
Without knowing how the IValidateApiTokenService needs to be instantiated, I can't give a specific recommendation, but there are a couple of examples of how to do it in the sample code (if you haven't take a look yet): github.com/ninject/Ninject.Web.WebApi/blob/master/src/…Coraleecoralie
G
3

in your Startup Class

public void Configuration(IAppBuilder app)
{    
    var kernel = new StandardKernel();
    // register IValidateApiTokenService
    var config = new HttpConfiguration();
    config.Filters.Add(new ApiAuthorizeFilter(kernel.Get<IValidateApiTokenService>());
}
Gerstein answered 24/5, 2016 at 12:56 Comment(0)
S
1

The reason it doesn't work per say is because ActionFilters (or any filters for that matter) are created as singletons by the runtime (one instance forever on the app context) and in general any DI container has problems wiring up a object's transient and or disposable dependencies if that object is a singleton.

One solution to your problem would be to use the built in service locator like so: DependencyResolver.Current.GetService(typeof(IValidateApiTokenService));

I don't personally use Ninject for my DI needs but if the above doesn't work it probably needs some wiring up in the DI startup or use a integration package like this one: https://github.com/ninject/ninject.web.mvc/wiki/MVC3

Scriven answered 23/5, 2016 at 20:5 Comment(0)
C
0

I never worked on Ninject, I worked on Unity. With my experience of working on Unity I will try to shed some light on the issue.

I am not sure what is the purpose of _validateApiTokenService, but what I can observer from the above code is that you have to configure to bind the dependency to the implementation IValidateApiTokenService. Along with the following code

kernel.BindHttpFilter<ApiAuthorizeFilter>(FilterScope.Controller);

you may have to have some thing like

kernel.Bind<IValidateApiTokenService>().To<ValidateApiTokenService>();

or

kernel.Bind<IValidateApiTokenService>.To<ValidateApiTokenService>().InSingletonScope(); 

if it is to be in Singleton scope.

Cryometer answered 19/5, 2016 at 11:30 Comment(1)
Thank you for replying. However, my question was specifically about getting Ninject's DI to work with ActionFilters. I have DI already working properly in controllers.Corrugation

© 2022 - 2024 — McMap. All rights reserved.