ASP.NET MVC3 + ActionFilterAttribute + Injection?
-
27-10-2019 - |
質問
ねえ、私は自分の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
}
前もって感謝します!
解決
いいえ、これはコンストラクターのパラメーターとして不可能です シンプルなタイプでなければなりません.
テストのために、別のコンストラクターを持つことができます(テストで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;
}
// ...
}
他のヒント
コンストラクターインジェクション は このシナリオでは可能ですが、属性/フィルターコンボを使用する必要があります。
フィルター(例: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;
}
}
次に、ニッジコンテナがフィルターへの属性をバインドします。
// controller-level
kernel.BindFilter<AuthorizationFilter>(FilterScope.Controller, 0).WhenControllerHas<RequireRolesAttribute>()
// action level
kernel.BindFilter<AuthorizationFilter>(FilterScope.Action, 0).WhenActionMethodHas<RequireRolesAttribute>();
見る:
ASP.NET MVCのNinjectおよびFilter属性による依存性注入
コンストラクター引数を使用したフィルターへのninjectバインディング属性
https://github.com/ninject/ninject.web.mvc/wiki/filter-configurations
私が克服しようとしているトリックは、フィルターへの属性で私の役割を定義する方法です... ninjectドキュメントは役立つはずですが、私はまだ自分自身ではありません。
幸運を。
所属していません StackOverflow