You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

170 lines
5.2 KiB

5 years ago
2 years ago
5 years ago
2 years ago
5 years ago
2 years ago
5 years ago
2 years ago
5 years ago
2 years ago
5 years ago
2 years ago
2 years ago
5 years ago
2 years ago
5 years ago
2 years ago
5 years ago
2 years ago
5 years ago
2 years ago
5 years ago
2 years ago
5 years ago
2 years ago
2 years ago
5 years ago
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Reflection;
  4. namespace Apewer.Web
  5. {
  6. /// <summary></summary>
  7. public sealed class ApiFunction : IToJson
  8. {
  9. #region fields
  10. ApiApplication _application = null;
  11. MethodInfo _method = null;
  12. Type _return = null;
  13. ApiParameter[] _parameters = null;
  14. string _name = null;
  15. string _lower = null;
  16. string _caption = null;
  17. string _description = null;
  18. bool _hidden = false;
  19. bool _unparallel = false;
  20. #endregion
  21. #region properties
  22. /// <summary></summary>
  23. public ApiApplication Application { get => _application; }
  24. /// <summary>方法。</summary>
  25. public MethodInfo Method { get => _method; }
  26. /// <summary>参数。</summary>
  27. public ApiParameter[] Parameters { get => _parameters.Map(x => x); }
  28. /// <summary>返回的类型。</summary>
  29. public Type ReturnType { get => _return; }
  30. /// <summary></summary>
  31. public string Name { get => _name; }
  32. /// <summary></summary>
  33. public string Caption { get => _caption; }
  34. /// <summary></summary>
  35. public string Description { get => _description; }
  36. /// <summary></summary>
  37. public bool Hidden { get => _hidden; }
  38. /// <summary></summary>
  39. public bool Unparallel { get => _unparallel; }
  40. #endregion
  41. /// <summary></summary>
  42. public Json ToJson() => ToJson(true);
  43. /// <summary></summary>
  44. public Json ToJson(ApiOptions options) => ToJson((options ?? new ApiOptions()).WithParameters);
  45. /// <summary></summary>
  46. public Json ToJson(bool withParameters)
  47. {
  48. if (Hidden) return null;
  49. var json = Json.NewObject();
  50. json.SetProperty("name", Name);
  51. if (!string.IsNullOrEmpty(Caption)) json.SetProperty("caption", Caption);
  52. if (!string.IsNullOrEmpty(Description)) json.SetProperty("description", Description);
  53. if (withParameters) json.SetProperty("parameters", Json.From(_parameters));
  54. return json;
  55. }
  56. ApiFunction(MethodInfo method, ApiApplication application, ApiParameter[] parameters)
  57. {
  58. // 检查 ApiAttribute 特性。
  59. var apis = method.GetCustomAttributes(typeof(ApiAttribute), false);
  60. var api = apis.Length > 0 ? (ApiAttribute)apis[0] : null;
  61. // Entry
  62. _application = application;
  63. _method = method;
  64. // 返回值。
  65. _return = method.ReturnType;
  66. if (_return.Equals(typeof(void))) _return = null;
  67. // api
  68. if (api == null)
  69. {
  70. _name = method?.Name;
  71. _lower = _name?.Lower();
  72. }
  73. else
  74. {
  75. _name = string.IsNullOrEmpty(api.Name) ? method?.Name : api.Name;
  76. _lower = _name?.Lower();
  77. _caption = api.Caption;
  78. _description = api.Description;
  79. }
  80. // caption
  81. if (string.IsNullOrEmpty(_caption))
  82. {
  83. var captions = method.GetCustomAttributes(typeof(CaptionAttribute), true);
  84. if (captions.Length > 0)
  85. {
  86. var caption = (CaptionAttribute)captions[0];
  87. _caption = caption.Title;
  88. if (string.IsNullOrEmpty(_description))
  89. {
  90. _description = caption.Description;
  91. }
  92. }
  93. }
  94. // hidden
  95. if (method.Contains<HiddenAttribute>(false)) _hidden = true;
  96. // unparallel
  97. if (method.Contains<UnparallelAttribute>(false)) _unparallel = true;
  98. // 参数。
  99. _parameters = parameters;
  100. }
  101. /// <summary></summary>
  102. public static ApiFunction Parse(ApiApplication application, MethodInfo method)
  103. {
  104. if (application == null) return null;
  105. if (method == null) return null;
  106. // 滤除构造函数、抽象方法、泛型和非本类定义方法。
  107. if (method.IsConstructor) return null;
  108. if (method.IsAbstract) return null;
  109. if (method.GetGenericArguments().NotEmpty()) return null;
  110. // 滤除 get 和 set 访问器。
  111. var methodName = method.Name;
  112. if (methodName.StartsWith("get_") || methodName.StartsWith("set_")) return null;
  113. switch (methodName)
  114. {
  115. case "Dispose":
  116. return null;
  117. }
  118. // 定义者。
  119. var declaring = method.DeclaringType;
  120. if (declaring.Equals(typeof(object))) return null;
  121. // 参数,所有参数必须是 In 方向。
  122. var ps = new List<ApiParameter>();
  123. foreach (var pi in method.GetParameters())
  124. {
  125. var p = ApiParameter.Parse(pi);
  126. if (p == null) return null;
  127. ps.Add(p);
  128. }
  129. return new ApiFunction(method, application, ps.ToArray());
  130. }
  131. }
  132. }