AttributeMap.cs 6.9 KB

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