ASP.NET MVC3 + ActionFilterAttribute + Injection?

后端 未结 2 1843
攒了一身酷
攒了一身酷 2020-12-10 15:03

Hey there, I\'ve succesfull been able to use property injection in my FilterAttribute, however I\'m wondering whether its possible to move it into the constructor instead?

相关标签:
2条回答
  • 2020-12-10 15:24

    No, this isn't possible as the parameters for the constructors must be simple types.

    For testing purposes, you could have another constructor (since you shouldn't be using an IoC container with testing):

    public class AuthAttribute : ActionFilterAttribute
    {
        public Roles _authRoles { get; private set; }
    
        [Inject]
        private readonly IAuthorizationService _service;
    
        public AuthAttribute(Roles roles)
        {
            _authRoles = roles;
        }
    
        public AuthAttribute(Roles roles, IAuthorizationService authSvc)
            : this(roles)
        {
            this.service = authSvc;
        }
    
        // ...
    }
    
    0 讨论(0)
  • 2020-12-10 15:26

    Constructor injection is possible in this scenario, but you need to use an Attribute/Filter combo.

    Your Filter (ex. : IAuthorizationFilter) implementation will use Constructor Injection and do all the work...

    Your Attribute (ex. : FilterAttribute) will be thin, mainly used to decorate your controllers or actions.

    public class AuthorizationFilter : IAuthorizationFilter
    {
        private readonly IAuthorizationService _authorizationService;
        private readonly UserRoles _requiredRoles; // Enum of Roles
    
        public AuthorizationFilter(IAuthorizationService authorizationService, UserRoles requiredRoles)
        {
            _authorizationService = authorizationService;
            _requiredRoles = requiredRoles;
        }
    
        public void OnAuthorization(AuthorizationContext filterContext)
        {
            // do work, or HandleUnauthorizedRequest()
        }
    
        protected void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            // do work
        }
    
    }
    
    public class RequireRolesAttribute : FilterAttribute
    {
        public readonly UserRoles RequiredRoles;
    
        public RequireRolesAttribute(UserRoles requiredRoles)
        {
            RequiredRoles = requiredRoles;
        }        
    }
    

    Then your Ninject container binds the Attribute to the Filter:

    // controller-level
    kernel.BindFilter<AuthorizationFilter>(FilterScope.Controller, 0).WhenControllerHas<RequireRolesAttribute>()
    // action level
    kernel.BindFilter<AuthorizationFilter>(FilterScope.Action, 0).WhenActionMethodHas<RequireRolesAttribute>();
    

    See:

    Dependency Injection with Ninject and Filter attribute for asp.net mvc

    Ninject Binding Attribute to Filter with Constructor Arguments

    https://github.com/ninject/ninject.web.mvc/wiki/Filter-configurations

    The trick I'm looking to overcome is how get my Roles defined on the attribute to the Filter... the ninject documentation should help but I'm not there yet myself.

    Good luck.

    0 讨论(0)
提交回复
热议问题