using System; using System.Collections.Generic; using System.Reflection; using System.Text; namespace Apewer.Web { /// 入口集合。 public sealed class ApiEntries : IToJson { #region instance object locker = new object(); SortedDictionary _apps = new SortedDictionary(); SortedDictionary _actions = new SortedDictionary(); internal ApiApplication GetApplication(string name) { if (string.IsNullOrEmpty(name)) return null; var key = name.ToLower(); lock (locker) { if (_apps.TryGetValue(key, out var value)) return value; } return null; } internal ApiAction GetAction(string path) { if (string.IsNullOrEmpty(path)) return null; var key = path.ToLower(); lock (locker) { if (_actions.TryGetValue(key, out var value)) return value; } return null; } /// public ApiApplication[] Applications { get => _apps.Values.Map(x => x); } /// public ApiAction[] Actions { get => _actions.Values.Map(x => x); } /// public ApiEntries() { } /// public ApiEntries(IEnumerable applications, IEnumerable actions, bool replace = false) : this() { Add(applications, replace); Add(actions, replace); } /// public ApiEntries(IEnumerable applications, bool replace = false) : this(applications, null, replace) { } /// public ApiEntries(ApiAction[] actions, bool replace = false) : this(null, actions, replace) { } /// 添加入口。 public void Add(IEnumerable applications, bool replace = false) { if (applications == null) return; lock (locker) { foreach (var app in applications) { if (app == null) continue; var appKey = app.Name.Lower(); if (appKey.IsEmpty()) continue; if (_apps.ContainsKey(appKey)) { if (replace) _apps[appKey] = app; } else { _apps.Add(appKey, app); } } } } /// 添加入口。 public void Add(IEnumerable actions, bool replace = false) { if (actions == null) return; lock (locker) { foreach (var action in actions) { if (action == null) continue; var actionKey = action.Path.Lower(); if (actionKey.IsEmpty()) continue; if (_actions.ContainsKey(actionKey)) { if (replace) _actions[actionKey] = action; } else { _actions.Add(actionKey, action); } } } } /// 追加指定的集合,指定 replace 参数将替换当前实例中的同名的入口。 public void Add(ApiEntries entries, bool replace = false) { if (entries == null) return; Add(entries.Applications, replace); Add(entries.Actions, replace); } /// 清空当前实例。 public void Clear() { lock (locker) { _apps.Clear(); _actions.Clear(); } } /// 生成 Json 实例。 public Json ToJson() { lock (locker) { var obj = new { applications = Applications, actions = Actions }; return Json.From(obj); } } #endregion #region static /// 从指定的程序集获取入口。 public static ApiEntries From(Assembly assembly, bool replace = false) { if (assembly == null) return null; var apps = new List(); var actions = new List(); var types = assembly.GetExportedTypes(); foreach (var type in types) { apps.Add(ApiApplication.Parse(type, true)); actions.AddRange(ApiAction.Parse(type)); } var entries = new ApiEntries(apps, actions, replace); return entries; } /// 从多个程序集中获取入口。 public static ApiEntries From(IEnumerable assemblies, bool replace = false) { if (assemblies == null) return null; var entries = new ApiEntries(); foreach (var assembly in assemblies) entries.Add(From(assembly), replace); return entries; } /// 从当前程序中获取入口。 public static ApiEntries Calling(bool replace = false) => From(Assembly.GetCallingAssembly(), replace); /// 从当前 AppDomain 中获取入口。 public static ApiEntries AppDomain(bool replace = false) => From(System.AppDomain.CurrentDomain.GetAssemblies(), replace); #endregion } }