2013-08-19 147 views
1

我目前(非常簡單化)用下面的代碼攔截工作:Ninject攔截屬性的參數傳遞給攔截器?

(見底部的問題)

我的攔截器:

public interface IAuthorizationInterceptor : IInterceptor { } 
public class AuthorizationInterceptor : IAuthorizationInterceptor 
{ 


    public IParameter[] AttributeParameters { get; private set; } 


    // This doesnt work currently... paramters has no values 
    public AuthorizationInterceptor(IParameter[] parameters) { 
     AttributeParameters = parameters; 
    } 

    public void Intercept(IInvocation invocation) { 
     // I have also tried to get the attributes like this 
     // which also returns nothing. 
     var attr = invocation.Request.Method.GetCustomAttributes(true); 


     try { 
      BeforeInvoke(invocation); 
     } catch (AccessViolationException ex) { 

     } catch (Exception ex) { 
      throw; 
     } 
     // Continue method and/or processing additional attributes 
     invocation.Proceed(); 
     AfterInvoke(invocation); 
    } 


    protected void BeforeInvoke(IInvocation invocation) { 

     // Enumerate parameters of method call 
     foreach (var arg in invocation.Request.Arguments) { 
      // Just a test to see if I can get arguments 
     } 

     //TODO: Replace with call to auth system code. 
     bool isAuthorized = true; 

     if (isAuthorized == true) { 
      // Do stuff    
     } 
     else { 
      throw new AccessViolationException("Failed"); 
     }    
    } 

    protected void AfterInvoke(IInvocation invocation) { 


    } 
} 

我的屬性:

public class AuthorizeAttribute : InterceptAttribute 
{ 
    public string[] AttributeParameters { get; private set; } 

    public AuthorizeAttribute(params string[] parameters) { 
     AttributeParameters = parameters; 
    } 

    public override IInterceptor CreateInterceptor(IProxyRequest request) { 
     var param = new List<Parameter>(); 
     foreach(string p in AttributeParameters) { 
      param.Add(new Parameter(p, p, false)); 
     } 
     // Here I have tried passing ConstructorArgument(s) but the result 
     // in the inteceptor constructor is the same. 
     return request.Context.Kernel.Get<IAuthorizationInterceptor>(param.ToArray()); 
    } 
} 

適用方法:

[Authorize("test")] 
public virtual Result<Vault> Vault(DateTime date, bool LiveMode = true, int? SnapshotId = null) 
{ 
     ... 
} 

這工作,我能夠通過這樣的屬性來傳遞額外的參數:

[Authorize("test")] 

如果你會發現在我的屬性,我抓住從屬性的一些參數,我能訪問屬性類,但我無法將它們傳遞給攔截器。我已經嘗試在Kernel.Get <>()調用中使用ConstructorArgument,它不會拋出錯誤,但AuthorizationInterceptor構造函數不會從ninject獲取任何值。我也嘗試過GetCustomAttributes(),你可以在代碼示例中看到,但是這也不會返回任何結果。從看起來像這樣的其他類似帖子(Ninject Interception 3.0 Interface proxy by method attributes)似乎是正確的方式,但它不起作用。有任何想法嗎?

+1

構造器參數應該工作。 (IEnumerable parameters)和Kernel.Get (新的ConstructorArgument – BatteryBackupUnit

回答

1

我能夠通過在攔截器上創建一個初始化方法來獲得工作。我不太喜歡它,因爲它將我與AuthorizationInterceptor的特定實現聯繫在一起,但它完成了工作(該死的截止日期大聲笑)。我仍然想知道是否有更好的方法來做到這一點,所以我不打算標記自己的答案,希望有人能夠以更好的方式來做到這一點。

我修改的屬性如下:

public override IInterceptor CreateInterceptor(IProxyRequest request) { 
     AuthorizationInterceptor attr = (AuthorizationInterceptor)request.Context.Kernel.Get<IAuthorizationInterceptor>(); 
     attr.Init(AttributeParameters); 
     return attr; 
    } 

而且在攔截器創建的初始化方法:

public void Init(params string[] parameters) { 
     AttributeParameters = parameters; 
    }