2013-01-23 27 views
0

內DynamicProxy攔截方法,我有:從財產生成的方法檢索CustomAttribute

public void Intercept(IInvocation invocation) 
    { 
     var _attribute = Attribute.GetCustomAttribute(invocation.Method, typeof(OneToManyAttribute), true); 

我飾我的財產是這樣的:

[OneToMany(typeof(Address), "IdUser")] 
public virtual IList<Address> Addresses { get; set; } 

_attribute總是null

我認爲問題是invocation.Method是自動生成get_Addresses而不是裝飾的原始屬性。

在這種情況下是否有解決方法來檢索屬性列表?

回答

1

你是對的 - invocation.Method將是屬性訪問器,而不是屬性。

這裏是一個要找到對應於它的存取方法之一PropertyInfo實用方法:

public static PropertyInfo PropertyInfoFromAccessor(MethodInfo accessor) 
{ 
    PropertyInfo result = null; 
    if (accessor != null && accessor.IsSpecialName) 
    { 
     string propertyName = accessor.Name; 
     if (propertyName != null && propertyName.Length >= 5) 
     { 
     Type[] parameterTypes; 
     Type returnType = accessor.ReturnType; 
     ParameterInfo[] parameters = accessor.GetParameters(); 
     int parameterCount = (parameters == null ? 0 : parameters.Length); 

     if (returnType == typeof(void)) 
     { 
      if (parameterCount == 0) 
      { 
       returnType = null; 
      } 
      else 
      { 
       parameterCount--; 
       returnType = parameters[parameterCount].ParameterType; 
      } 
     } 

     if (returnType != null) 
     { 
      parameterTypes = new Type[parameterCount]; 
      for (int index = 0; index < parameterTypes.Length; index++) 
      { 
       parameterTypes[index] = parameters[index].ParameterType; 
      } 

      try 
      { 
       result = accessor.DeclaringType.GetProperty(
        propertyName.Substring(4), 
        returnType, 
        parameterTypes); 
      } 
      catch (AmbiguousMatchException) 
      { 
      } 
     } 
     } 
    } 

    return result; 
} 

使用這種方法,你的代碼將成爲:

var _attribute = Attribute.GetCustomAttribute(invocation.Method, typeof(OneToManyAttribute), true); 
if (_attribute == null && invocation.Method.IsSpecialName) 
{ 
    var property = PropertyInfoFromAccessor(invocation.Method); 
    if (property != null) 
    { 
     _attribute = Attribute.GetCustomAttribute(property, typeof(OneToManyAttribute), true); 
    } 
} 

如果您OneToManyAttribute僅適用於性能,不是方法,你可以省略第一個電話GetCustomAttribute

var property = PropertyInfoFromAccessor(invocation.Method); 
var _attribute = (property == null) ? null : Attribute.GetCustomAttribute(property, typeof(OneToManyAttribute), true);