AttributeMap.cs 6.8 KB

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