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.

189 lines
5.8 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
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
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
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. using System.Text;
  5. namespace Apewer.Web
  6. {
  7. /// <summary>入口集合。</summary>
  8. public sealed class ApiEntries : IToJson
  9. {
  10. #region instance
  11. object locker = new object();
  12. SortedDictionary<string, ApiApplication> _apps = new SortedDictionary<string, ApiApplication>();
  13. SortedDictionary<string, ApiAction> _actions = new SortedDictionary<string, ApiAction>();
  14. internal ApiApplication GetApplication(string name)
  15. {
  16. if (string.IsNullOrEmpty(name)) return null;
  17. var key = name.ToLower();
  18. lock (locker)
  19. {
  20. if (_apps.TryGetValue(key, out var value)) return value;
  21. }
  22. return null;
  23. }
  24. internal ApiAction GetAction(string path)
  25. {
  26. if (string.IsNullOrEmpty(path)) return null;
  27. var key = path.ToLower();
  28. lock (locker)
  29. {
  30. if (_actions.TryGetValue(key, out var value)) return value;
  31. }
  32. return null;
  33. }
  34. /// <summary></summary>
  35. public ApiApplication[] Applications { get => _apps.Values.Map(x => x); }
  36. /// <summary></summary>
  37. public ApiAction[] Actions { get => _actions.Values.Map(x => x); }
  38. /// <summary></summary>
  39. public ApiEntries() { }
  40. /// <summary></summary>
  41. public ApiEntries(IEnumerable<ApiApplication> applications, IEnumerable<ApiAction> actions, bool replace = false) : this()
  42. {
  43. Add(applications, replace);
  44. Add(actions, replace);
  45. }
  46. /// <summary></summary>
  47. public ApiEntries(IEnumerable<ApiApplication> applications, bool replace = false) : this(applications, null, replace) { }
  48. /// <summary></summary>
  49. public ApiEntries(ApiAction[] actions, bool replace = false) : this(null, actions, replace) { }
  50. /// <summary>添加入口。</summary>
  51. public void Add(IEnumerable<ApiApplication> applications, bool replace = false)
  52. {
  53. if (applications == null) return;
  54. lock (locker)
  55. {
  56. foreach (var app in applications)
  57. {
  58. if (app == null) continue;
  59. var appKey = app.Name.Lower();
  60. if (appKey.IsEmpty()) continue;
  61. if (_apps.ContainsKey(appKey))
  62. {
  63. if (replace) _apps[appKey] = app;
  64. }
  65. else
  66. {
  67. _apps.Add(appKey, app);
  68. }
  69. }
  70. }
  71. }
  72. /// <summary>添加入口。</summary>
  73. public void Add(IEnumerable<ApiAction> actions, bool replace = false)
  74. {
  75. if (actions == null) return;
  76. lock (locker)
  77. {
  78. foreach (var action in actions)
  79. {
  80. if (action == null) continue;
  81. var actionKey = action.Path.Lower();
  82. if (actionKey.IsEmpty()) continue;
  83. if (_actions.ContainsKey(actionKey))
  84. {
  85. if (replace) _actions[actionKey] = action;
  86. }
  87. else
  88. {
  89. _actions.Add(actionKey, action);
  90. }
  91. }
  92. }
  93. }
  94. /// <summary>追加指定的集合,指定 replace 参数将替换当前实例中的同名的入口。</summary>
  95. public void Add(ApiEntries entries, bool replace = false)
  96. {
  97. if (entries == null) return;
  98. Add(entries.Applications, replace);
  99. Add(entries.Actions, replace);
  100. }
  101. /// <summary>清空当前实例。</summary>
  102. public void Clear()
  103. {
  104. lock (locker)
  105. {
  106. _apps.Clear();
  107. _actions.Clear();
  108. }
  109. }
  110. /// <summary>生成 Json 实例。</summary>
  111. public Json ToJson()
  112. {
  113. lock (locker)
  114. {
  115. var obj = new
  116. {
  117. applications = Applications,
  118. actions = Actions
  119. };
  120. return Json.From(obj);
  121. }
  122. }
  123. #endregion
  124. #region static
  125. /// <summary>从指定的程序集获取入口。</summary>
  126. public static ApiEntries From(Assembly assembly, bool replace = false)
  127. {
  128. if (assembly == null) return null;
  129. var apps = new List<ApiApplication>();
  130. var actions = new List<ApiAction>();
  131. var types = assembly.GetExportedTypes();
  132. foreach (var type in types)
  133. {
  134. apps.Add(ApiApplication.Parse(type, true));
  135. actions.AddRange(ApiAction.Parse(type));
  136. }
  137. var entries = new ApiEntries(apps, actions, replace);
  138. return entries;
  139. }
  140. /// <summary>从多个程序集中获取入口。</summary>
  141. public static ApiEntries From(IEnumerable<Assembly> assemblies, bool replace = false)
  142. {
  143. if (assemblies == null) return null;
  144. var entries = new ApiEntries();
  145. foreach (var assembly in assemblies) entries.Add(From(assembly), replace);
  146. return entries;
  147. }
  148. /// <summary>从当前程序中获取入口。 </summary>
  149. public static ApiEntries Calling(bool replace = false) => From(Assembly.GetCallingAssembly(), replace);
  150. /// <summary>从当前 AppDomain 中获取入口。</summary>
  151. public static ApiEntries AppDomain(bool replace = false) => From(System.AppDomain.CurrentDomain.GetAssemblies(), replace);
  152. #endregion
  153. }
  154. }