How to use Ninject to inject services into an authorization filter?

I am using asp.net mvc 3, ninject 2.0 and the ninject mvc 3 plugin.

I am wondering how to get service layers in my filter (in this case, an authorization filter?).

I like to do constructor injection, is it possible or do I need to add a property?

thanks

Edit

I have this for inject property, but my property is always null

[Inject] public IAccountService AccountServiceHelper { get; set; } protected override bool AuthorizeCore(HttpContextBase httpContext) { // check if context is set if (httpContext == null) { throw new ArgumentNullException("httpContext"); } // check if user is authenticated if (httpContext.User.Identity.IsAuthenticated == true) { // stuff here return true; } return false; } /// <summary> /// Application_Start /// </summary> protected void Application_Start() { // Hook our DI stuff when application starts IKernel kernel = SetupDependencyInjection(); RegisterMaps.Register(); AreaRegistration.RegisterAllAreas(); RegisterGlobalFilters(GlobalFilters.Filters); RegisterRoutes(RouteTable.Routes); } public IKernel SetupDependencyInjection() { IKernel kernel = CreateKernel(); // Tell ASP.NET MVC 3 to use our Ninject DI Container DependencyResolver.SetResolver(new NinjectDependencyResolver(kernel)); return kernel; } protected IKernel CreateKernel() { var modules = new INinjectModule[] { new NhibernateModule(), new ServiceModule(), new RepoModule() }; return new StandardKernel(modules); } public class ServiceModule : NinjectModule { public override void Load() { Bind<IAccountService>().To<AccountService>(); } } 

Edit

I upgraded to ninject 2.2 and finally got the job.

Edit 2

I am going to try and execute the constructor for my credentials filter, but I'm not sure how to go about in Roles. I guess I should do it through ninject?

Edit 3

This is what I still have

  public class MyAuthorizeAttribute : AuthorizeAttribute { private readonly IAccountService accountService; public MyAuthorizeAttribute(IAccountService accountService) { this.accountService = accountService; } protected override bool AuthorizeCore(HttpContextBase httpContext) { return base.AuthorizeCore(httpContext); } } this.BindFilter<MyAuthorizeAttribute>(FilterScope.Controller, 0) .WhenControllerHas<MyAuthorizeAttribute>(); [MyAuthorize] public class MyController : BaseController { } 

He tells me that he needs a no parameter constructor. So something is missing me.

+7
source share
2 answers

The problem with filters is that they are attributes. And if you define an attribute constructor that expects some dependency, you can never apply it to any method: because all the values ​​you pass to the attributes must be known at compile time.

So, you have two options:

  • Use Ninject to apply the filter globally instead of decorating your controllers / actions with it:

     public interface IFoo { } public class Foo : IFoo { } public class MyFooFilter : AuthorizeAttribute { public MyFooFilter(IFoo foo) { } } 

    and then configure the kernel:

     kernel.Bind<IFoo>().To<Foo>(); kernel.BindFilter<MyFooFilter>(FilterScope.Action, 0).When( (controllerContext, actionDescriptor) => string.Equals( controllerContext.RouteData.GetRequiredString("controller"), "home", StringComparison.OrdinalIgnoreCase ) ); 
  • Use injection properties:

     public interface IFoo { } public class Foo : IFoo { } public class MyFooFilter : AuthorizeAttribute { [Inject] public IFoo Foo { get; set; } } 

    and then configure the kernel:

     kernel.Bind<IFoo>().To<Foo>(); 

    and decorate any controller / action with your custom filter:

     [MyFooFilter] public ActionResult Index() { return View(); } 
+11
source

All Articles