ASP.NET MVC3 + ActionFilterAttribute + Injection? - PullRequest
10 голосов
/ 29 января 2011

Привет, я успешно смог использовать инъекцию свойств в моем FilterAttribute, однако мне интересно, можно ли вместо этого переместить его в конструктор?

Мой текущий код:

// AuthAttribute.cs

public class AuthAttribute : ActionFilterAttribute
{
    public Roles _authRoles { get; private set; }

    [Inject]
    private readonly IAuthorizationService _service;

    public AuthAttribute(Roles roles)
    {
        _authRoles = roles;
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
        {
            string redirectOnSuccess = filterContext.HttpContext.Request.Url.AbsolutePath;
            string redirectUrl = string.Format("?returnUrl={0}", redirectOnSuccess);
            string loginUrl = FormsAuthentication.LoginUrl + redirectUrl;

            filterContext.HttpContext.Response.Redirect(loginUrl, true);
        }
        else
        {
            bool isAuthorized = _service.Authorize(GetUserSession.Id, _authRoles.ToString());

            if (!isAuthorized)
            {
                // TODO: Make custom "Not Authorized" error page.
                throw new UnauthorizedAccessException("No access");
            }
        }
    }
}

// TestController.cs

[Auth(Roles.Developer)]
public ActionResult Index()
{
    // Some smart logic
}

Заранее спасибо!

Ответы [ 2 ]

8 голосов
/ 30 января 2011

Нет, это невозможно, поскольку параметры для конструкторов должны быть простых типов .

В целях тестирования у вас может быть другой конструктор (поскольку вам не следует использовать контейнер IoC с тестированием):

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

    // ...
}
7 голосов
/ 30 ноября 2011

Внедрение в конструктор возможно в этом сценарии, но вам нужно использовать комбо Атрибут / Фильтр.

Ваша реализация фильтра (например: IAuthorizationFilter) будет использовать Внедрение в конструктор и делать всеработа ...

Ваш атрибут (например, FilterAttribute) будет тонким, в основном используется для украшения ваших контроллеров или действий.

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

Затем ваш контейнер Ninject связывает атрибут сФильтр:

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

См .:

Внедрение зависимостей с атрибутом Ninject и Filter для asp.net mvc

Атрибут привязки NinjectФильтр с аргументами конструктора

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

Уловка, которую я хочу преодолеть, заключается в том, как определить мои роли в атрибуте фильтра ... вспомогательная документация должна помочьно я еще не там.

Удачи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...