2013-08-19 119 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; 
    }