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.

163 lines
4.9 KiB

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