AttributeMap.cs 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. #if !NO_RUNTIME
  2. using System;
  3. using System.Linq;
  4. #if FEAT_IKVM
  5. using Type = IKVM.Reflection.Type;
  6. using IKVM.Reflection;
  7. #else
  8. using System.Reflection;
  9. #endif
  10. namespace ProtoBuf.Meta
  11. {
  12. internal abstract class AttributeMap
  13. {
  14. #if DEBUG
  15. [Obsolete("Please use AttributeType instead")]
  16. new public Type GetType() { return AttributeType; }
  17. #endif
  18. public override string ToString() => AttributeType?.FullName ?? "";
  19. public abstract bool TryGet(string key, bool publicOnly, out object value);
  20. public bool TryGet(string key, out object value)
  21. {
  22. return TryGet(key, true, out value);
  23. }
  24. public abstract Type AttributeType { get; }
  25. public static AttributeMap[] Create(TypeModel model, Type type, bool inherit)
  26. {
  27. #if FEAT_IKVM
  28. Type attribType = model.MapType(typeof(System.Attribute));
  29. System.Collections.Generic.IList<CustomAttributeData> all = type.__GetCustomAttributes(attribType, inherit);
  30. AttributeMap[] result = new AttributeMap[all.Count];
  31. int index = 0;
  32. foreach (CustomAttributeData attrib in all)
  33. {
  34. result[index++] = new AttributeDataMap(attrib);
  35. }
  36. return result;
  37. #else
  38. #if WINRT || COREFX
  39. Attribute[] all = System.Linq.Enumerable.ToArray(type.GetTypeInfo().GetCustomAttributes(inherit));
  40. #else
  41. //object[] all = type.GetCustomAttributes(inherit);
  42. // 过滤掉null的Attribute
  43. object[] all = type.GetCustomAttributes(inherit).Where((x)=>x != null).ToArray();
  44. #endif
  45. AttributeMap[] result = new AttributeMap[all.Length];
  46. for(int i = 0 ; i < all.Length ; i++)
  47. {
  48. result[i] = new ReflectionAttributeMap((Attribute)all[i]);
  49. }
  50. return result;
  51. #endif
  52. }
  53. public static AttributeMap[] Create(TypeModel model, MemberInfo member, bool inherit)
  54. {
  55. #if FEAT_IKVM
  56. System.Collections.Generic.IList<CustomAttributeData> all = member.__GetCustomAttributes(model.MapType(typeof(Attribute)), inherit);
  57. AttributeMap[] result = new AttributeMap[all.Count];
  58. int index = 0;
  59. foreach (CustomAttributeData attrib in all)
  60. {
  61. result[index++] = new AttributeDataMap(attrib);
  62. }
  63. return result;
  64. #else
  65. #if WINRT || COREFX
  66. Attribute[] all = System.Linq.Enumerable.ToArray(member.GetCustomAttributes(inherit));
  67. #else
  68. //object[] all = member.GetCustomAttributes(inherit);
  69. // 过滤掉null的Attribute
  70. object[] all = member.GetCustomAttributes(inherit).Where((x)=>x != null).ToArray();
  71. #endif
  72. AttributeMap[] result = new AttributeMap[all.Length];
  73. for(int i = 0 ; i < all.Length ; i++)
  74. {
  75. result[i] = new ReflectionAttributeMap((Attribute)all[i]);
  76. }
  77. return result;
  78. #endif
  79. }
  80. public static AttributeMap[] Create(TypeModel model, Assembly assembly)
  81. {
  82. #if FEAT_IKVM
  83. const bool inherit = false;
  84. System.Collections.Generic.IList<CustomAttributeData> all = assembly.__GetCustomAttributes(model.MapType(typeof(Attribute)), inherit);
  85. AttributeMap[] result = new AttributeMap[all.Count];
  86. int index = 0;
  87. foreach (CustomAttributeData attrib in all)
  88. {
  89. result[index++] = new AttributeDataMap(attrib);
  90. }
  91. return result;
  92. #else
  93. #if WINRT || COREFX
  94. Attribute[] all = System.Linq.Enumerable.ToArray(assembly.GetCustomAttributes());
  95. #else
  96. const bool inherit = false;
  97. //object[] all = assembly.GetCustomAttributes(inherit);
  98. // 过滤掉null的Attribute
  99. object[] all = assembly.GetCustomAttributes(inherit).Where((x)=>x != null).ToArray();
  100. #endif
  101. AttributeMap[] result = new AttributeMap[all.Length];
  102. for(int i = 0 ; i < all.Length ; i++)
  103. {
  104. result[i] = new ReflectionAttributeMap((Attribute)all[i]);
  105. }
  106. return result;
  107. #endif
  108. }
  109. #if FEAT_IKVM
  110. private sealed class AttributeDataMap : AttributeMap
  111. {
  112. public override Type AttributeType
  113. {
  114. get { return attribute.Constructor.DeclaringType; }
  115. }
  116. private readonly CustomAttributeData attribute;
  117. public AttributeDataMap(CustomAttributeData attribute)
  118. {
  119. this.attribute = attribute;
  120. }
  121. public override bool TryGet(string key, bool publicOnly, out object value)
  122. {
  123. foreach (CustomAttributeNamedArgument arg in attribute.NamedArguments)
  124. {
  125. if (string.Equals(arg.MemberInfo.Name, key, StringComparison.OrdinalIgnoreCase))
  126. {
  127. value = arg.TypedValue.Value;
  128. return true;
  129. }
  130. }
  131. int index = 0;
  132. ParameterInfo[] parameters = attribute.Constructor.GetParameters();
  133. foreach (CustomAttributeTypedArgument arg in attribute.ConstructorArguments)
  134. {
  135. if (string.Equals(parameters[index++].Name, key, StringComparison.OrdinalIgnoreCase))
  136. {
  137. value = arg.Value;
  138. return true;
  139. }
  140. }
  141. value = null;
  142. return false;
  143. }
  144. }
  145. #else
  146. public abstract object Target { get; }
  147. private sealed class ReflectionAttributeMap : AttributeMap
  148. {
  149. public override object Target
  150. {
  151. get { return attribute; }
  152. }
  153. public override Type AttributeType
  154. {
  155. get { return attribute.GetType(); }
  156. }
  157. public override bool TryGet(string key, bool publicOnly, out object value)
  158. {
  159. MemberInfo[] members = Helpers.GetInstanceFieldsAndProperties(attribute.GetType(), publicOnly);
  160. foreach (MemberInfo member in members)
  161. {
  162. #if FX11
  163. if (member.Name.ToUpper() == key.ToUpper())
  164. #else
  165. if (string.Equals(member.Name, key, StringComparison.OrdinalIgnoreCase))
  166. #endif
  167. {
  168. PropertyInfo prop = member as PropertyInfo;
  169. if (prop != null) {
  170. //value = prop.GetValue(attribute, null);
  171. value = prop.GetGetMethod(true).Invoke(attribute, null);
  172. return true;
  173. }
  174. FieldInfo field = member as FieldInfo;
  175. if (field != null) {
  176. value = field.GetValue(attribute);
  177. return true;
  178. }
  179. throw new NotSupportedException(member.GetType().Name);
  180. }
  181. }
  182. value = null;
  183. return false;
  184. }
  185. private readonly Attribute attribute;
  186. public ReflectionAttributeMap(Attribute attribute)
  187. {
  188. this.attribute = attribute;
  189. }
  190. }
  191. #endif
  192. }
  193. }
  194. #endif