2013-08-23 69 views
4

I'musing的ASP.NET Web API,我需要獲得授權,所以我已經創建自定義授權屬性自定義過濾器的屬性注入依賴

public class CustomAuthorizationAttribute : AuthorizeAttribute 

爲了注入內部構造依賴我有以下幾點:

 public CustomAuthorizationAttribute(IAccountBL accountBl) 
    { 
     _accountBL = accountBl; 
    } 

IAccountBL我有方法與數據庫檢查交互如果用戶被授權發出請求。 內部會員API控制器我已經註冊該屬性

[CustomAuthorization] 
public class MemberController : ApiController 

,但我得到以下錯誤

Project.Account.AccountBL」不包含一個構造函數參數0

如果我註冊它就像

[CustomAuthorization(IAccountBL)] 

enter image description here

謝謝

+1

這可能幫助:http://stackoverflow.com/questions/6193414/依賴注入與ninject和過濾器屬性的asp網絡mvc –

回答

1

如果有人發現類似的問題,這是我如何設法解決它。

我的自定義過濾器繼承IAutofacAuthorizationFilter。除此之外,您還可以繼承IAutofacExceptionFilterIAutofacActionFilter。 我的DI容器內我已經註冊該過濾器爲每個控制器我想用這樣的

 builder.Register(c => new CustomAuthorizationAttribute(c.Resolve<IAccountBL>())) 
       .AsWebApiAuthorizationFilterFor<MemberController>() 
       .InstancePerApiRequest(); 
8

行動過濾器只是屬性。您無法控制CLR實例化這些屬性的時間。一種可能性是寫一個標記屬性:

public class CustomAuthorizationAttribute : Attribute { } 

,然後實際操作篩選:

public class CustomAuthorizationFilter : ActionFilterAttribute 
{ 
    private readonly IAccountBL accountBL; 
    public CustomAuthorizationFilter(IAccountBL accountBL) 
    { 
     this.accountBL = accountBL; 
    } 

    public override void OnActionExecuting(HttpActionContext actionContext) 
    { 
     if (actionContext.ControllerContext.ControllerDescriptor.GetCustomAttributes<CustomAuthorizationAttribute>().Any() || 
      actionContext.ActionDescriptor.GetCustomAttributes<CustomAuthorizationAttribute>().Any()) 
     { 
      // here you know that the controller or action is decorated 
      // with the marker attribute so that you could put your code 
     } 
    } 
} 

,並最終把它註冊爲一個全球性的動作過濾器:

public static class WebApiConfig 
{ 
    public static void Register(HttpConfiguration config) 
    { 
     ... 

     IAccountBL accountBL = ... 
     config.Filters.Add(new CustomAuthorizationFilter(accountBL)); 
    } 
} 

最後你可以使用標記屬性:

[CustomAuthorization] 
public class MemberController : ApiController 
{ 
    ... 
} 
+0

我爲我的無知道歉,請你解釋我這部分 'IAccountBL accountBL = ...'因爲我正在注入對AccountBL的依賴?初始化如何進行? – jasenkoh

+0

您可以從DI容器中檢索它。 –

+0

我剛開始使用DI,這對我來說是全新的世界。你能幫我嗎,我如何從DI容器中取回它?我有註冊模塊,過濾器和控制器的AutoFacDependencyResolver類。 – jasenkoh

4

您可以通過使用擴展方法GetDependencyScopeHttpRequestMessage類讓你的過濾器的依賴。這不是依賴注入的規範方式,但可以用作解決方法。一個基本的例子可能是這樣的:

public Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken) 
    { 
     var dependencyScope = context.Request.GetDependencyScope(); 
     var dependency = dependencyScope.GetService(typeof (MyDependencyType)); 
     //use your dependency here 
    } 

這種方法可以與構造器注入來簡化單元測試:

public class MyAuthenticationFilter : Attribute, IAuthenticationFilter 
{ 
    private Func<HttpRequestMessage, MyDependencyType> _dependencyFactory; 

    public MyAuthenticationFilter() : 
     this(request => (MyDependencyType)request.GetDependencyScope().GetService(typeof(MyDependencyType))) 
    { 
    } 

    public MyAuthenticationFilter(Func<HttpRequestMessage, MyDependencyType> dependencyFactory) 
    { 
     _dependencyFactory = dependencyFactory; 
    } 

    public Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken) 
    { 
     var dependencyScope = context.Request.GetDependencyScope(); 
     var dependency = dependencyFactory.Invoke(context.Request); 
     //use your dependency here 
    } 

    public Task ChallengeAsync(HttpAuthenticationChallengeContext context, CancellationToken cancellationToken) 
    { 
     throw new NotImplementedException(); 
    } 

    public bool AllowMultiple { get; private set; } 
}